Объект people - это не список, а словарь, который вы не можете перебрать в словаре, подобном этому. Это должно сработать.
my_url = 'www.domain.com'
my_data = json.loads(requests.get(my_url).text)
for id , person in my_data['people'].items():
print(person['info']['name'])
Как другие упомянули, Вы, вероятно, захотите использовать BigDecimal
класс, если Вы хотите иметь точное представление 11,4.
Теперь, немного объяснения в то, почему это происходит:
float
и double
типы примитивов в Java являются числами с плавающей точкой, где число хранится как двоичное представление части и экспоненты.
Строго говоря, значение с плавающей точкой двойной точности такой как double
тип является 64-разрядным значением, где:
Эти части объединены для создания a double
представление значения.
(Источник: Википедия: Двойная точность)
Для подробного описания того, как значения с плавающей точкой обрабатываются в Java, посмотрите Раздел 4.2.3: Типы с плавающей точкой, Форматы и Значения Спецификации языка Java.
byte
, char
, int
, long
типы являются числами фиксированной точки, которые являются точным representions чисел. В отличие от чисел фиксированной точки, числа с плавающей точкой будут несколько раз (безопасный принять "большую часть времени") не смочь возвратить точное представление числа. Это - причина, почему Вы заканчиваете с 11.399999999999
как результат 5.6 + 5.8
.
При требовании значения, которое точно, такой как 1,5 или 150.1005, Вы захотите использовать один из типов фиксированной точки, которые смогут представить число точно.
Как несколько раз уже был упомянут, Java имеет a BigDecimal
класс, который обработает очень большие количества и очень небольшие числа.
От Java ссылка API для BigDecimal
класс:
Неизменная, произвольная точность подписала десятичные числа. BigDecimal состоит из целого числа произвольной точности немасштабированное значение и 32-разрядный целочисленный масштаб. Если нуль или положительный, масштаб является количеством цифр направо от десятичной точки. Если отрицательный, немасштабированное значение числа умножается на десять к питанию отрицания масштаба. Значение числа, представленного BigDecimal, поэтому (unscaledValue × 10^-scale).
Было много вопросов на Переполнении стека, касающемся вопроса чисел с плавающей точкой и его точности. Вот список связанных вопросов, которые могут представлять интерес:
Если Вы действительно хотите перейти к вшивым песчаным деталям чисел с плавающей точкой, смотреть на то, Что Каждый Программист Должен Знать Об Арифметике С плавающей точкой.
Используйте BigDecimal. Это даже позволяет Вам указать округление правил (как ROUND_HALF_EVEN, который минимизирует статистическую ошибку путем округления ровному соседу, если оба будут тем же расстоянием; т.е. и 1,5 и 2,5 раунда к 2).
Удваивается приближения десятичных чисел в Вашем источнике Java. Вы видите последствие несоответствия между двойным (который является двоично кодированным значением), и Ваш источник (который кодируется десятичным числом).
Создание Java самое близкое двоичное приближение. Можно использовать java.text. DecimalFormat для отображения лучше выглядящего десятичного значения.
Умножьте все на 100 и сохраните его в длинном как центы.
Как другие отметили, не, все десятичные значения могут быть представлены как двоичный файл, так как десятичное число основано на полномочиях 10, и двоичный файл основан на полномочиях два.
Если точность имеет значение, используйте BigDecimal, но если Вы просто хотите дружественный вывод:
System.out.printf("%.2f\n", total);
Даст Вам:
11.40
Вполне уверенный Вы, возможно, превратили это в три примера строки.:)
Если Вы хотите точную точность, используйте BigDecimal. Иначе можно использовать ints, умноженный на 10 ^ безотносительно точности, которую Вы хотите.
Заметьте, что у Вас была бы та же проблема, если бы Вы использовали десятичную систему счисления ограниченной точности и хотели иметь дело с 1/3: 0.333333333 * 3 0.999999999, не 1.00000000.
К сожалению, 5.6, 5.8 и 11.4 просто не круглые числа в двоичном файле, потому что они включают пятые. Таким образом, представление плавающее их не точно, так же, как 0.3333 не точно 1/3.
Если все числа, которые Вы используете, являются непериодическими десятичными числами, и Вы хотите точные результаты, используете BigDecimal. Или поскольку другие сказали, если Ваши значения похожи на деньги в том смысле, что они - все несколько из 0,01, или 0.001, или что-то, затем умножают все на фиксированное питание 10 и используют интервал или долго (дополнение, и вычитание тривиальны: не упустите умножение).
Однако, если Вы довольны двоичным файлом для вычисления, но Вы просто хотите распечатать вещи в немного более дружественном формате, попробовать java.util.Formatter
или String.format
. В строке формата указывают точность меньше, чем полная точность двойного. К 10 значащим цифрам, скажем, 11.399999999999 11.4, таким образом, результат будет почти как точный и более человекочитаемый в случаях, где двоичный результат очень близко к значению, требующему только нескольких десятичных разрядов.
Точность для определения зависит немного от того, сколько математики Вы сделали со своими числами - в целом, чем больше Вы делаете, тем больше ошибки накопится, но некоторые алгоритмы накапливают ее намного быстрее, чем другие (их называют "нестабильными" в противоположность "стабильному" относительно погрешностей округления). Если бы все, что Вы делаете, добавляет несколько значений, то я предположил бы, что отбрасывание всего одного десятичного разряда точности уладит вещи. Эксперимент.
Вы сталкиваетесь с ограничением точности типа double.
Java.Math имеет некоторые арифметические средства произвольной точности.
Когда вы вводите двойное число, например 33.33333333333333
, вы получаете значение, которое на самом деле является ближайшим представимым значением двойной точности, а именно:
33.3333333333333285963817615993320941925048828125
Деление этого на 100 дает:
0.333333333333333285963817615993320941925048828125
, который также не может быть представлен в виде числа с двойной точностью, поэтому оно снова округляется до ближайшего представимого значения, которое является точным:
0.3333333333333332593184650249895639717578887939453125
Когда вы распечатываете это значение, оно снова округляется до 17 десятичных цифр, что дает:
0.33333333333333326
Вы не можете, потому что 7.3 не имеет конечного представления в двоичном формате. Ближайшее, что вы можете получить, - это 2054767329987789/2 ** 48 = 7,3 + 1/1407374883553280.
Дополнительное объяснение можно найти на http://docs.python.org/tutorial/floatingpoint.html . (Это на веб-сайте Python, но у Java и C ++ одна и та же «проблема».)
Решение зависит от того, в чем именно заключается ваша проблема:
Используйте java.math.BigDecimal
Двойные числа внутренне являются двоичными дробями, поэтому они иногда не могут представлять десятичные дроби с точностью до десятичной.
Обратите внимание на BigDecimal, он решает проблемы, связанные с арифметикой с плавающей запятой, подобной этой.
Новый вызов будет выглядеть так:
term[number].coefficient.add(co);
Используйте setScale (), чтобы установить количество используемых десятичных знаков точности.
Вы можете рассмотреть возможность использования класса java.math.BigDecimal, если вам действительно нужна точная математика. Вот хорошая статья от Oracle/Sun о преимуществах BigDecimal. Хотя вы никогда не сможете представить 1/3, как кто-то упомянул, вы можете решить, насколько точным вы хотите видеть результат. setScale() - ваш друг... :)
Хорошо, поскольку у меня сейчас слишком много свободного времени, вот пример кода, который относится к вашему вопросу:
import java.math.BigDecimal;
/**
* Created by a wonderful programmer known as:
* Vincent Stoessel
* xaymaca@gmail.com
* on Mar 17, 2010 at 11:05:16 PM
*/
public class BigUp {
public static void main(String[] args) {
BigDecimal first, second, result ;
first = new BigDecimal("33.33333333333333") ;
second = new BigDecimal("100") ;
result = first.divide(second);
System.out.println("result is " + result);
//will print : result is 0.3333333333333333
}
}
и чтобы подключить мой новый любимый язык Groovy, вот более аккуратный пример того же самого:
import java.math.BigDecimal
def first = new BigDecimal("33.33333333333333")
def second = new BigDecimal("100")
println "result is " + first/second // will print: result is 0.33333333333333
Если вы просто хотите обрабатывать значения в виде дробей, вы можете создать класс Fraction, который содержит поле числителя и знаменателя.
Напишите методы для сложения, вычитания, умножения и деления, а также метод toDouble. Таким образом, вы сможете избежать использования плавающих чисел во время вычислений.
EDIT: Быстрая реализация,
public class Fraction {
private int numerator;
private int denominator;
public Fraction(int n, int d){
numerator = n;
denominator = d;
}
public double toDouble(){
return ((double)numerator)/((double)denominator);
}
public static Fraction add(Fraction a, Fraction b){
if(a.denominator != b.denominator){
double aTop = b.denominator * a.numerator;
double bTop = a.denominator * b.numerator;
return new Fraction(aTop + bTop, a.denominator * b.denominator);
}
else{
return new Fraction(a.numerator + b.numerator, a.denominator);
}
}
public static Fraction divide(Fraction a, Fraction b){
return new Fraction(a.numerator * b.denominator, a.denominator * b.numerator);
}
public static Fraction multiply(Fraction a, Fraction b){
return new Fraction(a.numerator * b.numerator, a.denominator * b.denominator);
}
public static Fraction subtract(Fraction a, Fraction b){
if(a.denominator != b.denominator){
double aTop = b.denominator * a.numerator;
double bTop = a.denominator * b.numerator;
return new Fraction(aTop-bTop, a.denominator*b.denominator);
}
else{
return new Fraction(a.numerator - b.numerator, a.denominator);
}
}
}
Компьютеры хранят числа в двоичном формате и не могут точно представлять такие числа, как 33,333333333 или 100,0. Это одна из сложностей при использовании двойников. Вам нужно будет просто округлить ответ, прежде чем показывать его пользователю. К счастью, в большинстве приложений такое количество десятичных знаков не требуется.
Числа с плавающей запятой отличаются от действительных чисел тем, что для любого заданного числа с плавающей запятой существует следующее более высокое число с плавающей запятой. То же, что и целые числа. Между 1 и 2 нет целого числа.
Невозможно представить 1/3 как число с плавающей запятой. Под ним есть поплавок, над ним - поплавок, и между ними есть определенное расстояние. И 1/3 находится в этом месте.
Apfloat для Java утверждает, что работает с числами с плавающей запятой произвольной точности, но я никогда не использовал его. Наверное, стоит взглянуть. http://www.apfloat.org/apfloat_java/
Аналогичный вопрос задавался здесь перед Библиотека высокой точности с плавающей запятой Java
Не тратьте усилия на использование BigDecimal. В 99.99999% случаев он вам не нужен. java double тип, конечно, приблизительный, но почти во всех случаях он достаточно точен. Имейте в виду, что у вас есть ошибка на 14-й значащей цифре. Это действительно ничтожно мало!
Для получения красивого результата используйте:
System.out.printf("%.2f\n", total);