Почему делает (интервал) (33.46639 * 1000000), возвращаются 33466389?

(int)(33.46639 * 1000000) возвраты 33466389

Почему это происходит?

18
задан Tim 11 June 2014 в 08:33
поделиться

7 ответов

Математика с плавающей запятой не идеальна. Что должен знать каждый программист об этом.

Многие люди считают арифметику с плавающей точкой эзотерикой. Это довольно удивительно, потому что числа с плавающей запятой широко используются в компьютерных системах. Почти каждый язык имеет тип данных с плавающей запятой; компьютеры от ПК до суперкомпьютеров имеют ускорители с плавающей запятой; большинству компиляторов будет время от времени приходиться компилировать алгоритмы с плавающей запятой; и практически каждая операционная система должна реагировать на исключения с плавающей запятой, такие как переполнение. Эта статья представляет собой учебное пособие по тем аспектам операций с плавающей запятой, которые оказывают непосредственное влияние на разработчиков компьютерных систем. Он начинается с общих сведений о представлении с плавающей запятой и ошибке округления, продолжается обсуждением стандарта IEEE с плавающей запятой и заканчивается многочисленными примерами того, как сборщики компьютеров могут лучше поддерживать числа с плавающей запятой.

...

Сжатие бесконечного числа действительных чисел в конечное число битов требует приближенного представления. Хотя целых чисел бесконечно много, в большинстве программ результат целочисленных вычислений может храниться в 32-битном формате. Напротив, при любом фиксированном количестве битов большинство вычислений с действительными числами будут производить величины, которые невозможно точно представить с помощью такого количества битов. Поэтому результат вычисления с плавающей запятой часто должен округляться, чтобы снова уместиться в его конечном представлении. Эта ошибка округления является характерной чертой вычислений с плавающей запятой.

31
ответ дан 30 November 2019 в 06:59
поделиться

Если вы спрашиваете, почему это не становится 33466390 , потому что double s не имеют бесконечной точности, и число не может быть точно выражено в двоичном формате.

Если заменить double десятичным ( (int) (33,46639m * 1000000) ), он будет равен 33466390 , потому что десятичные s вычисляются по основанию 10.

1
ответ дан 30 November 2019 в 06:59
поделиться

Причина, по которой вы получили другой результат, заключается в том, что вы использовали ' преобразование '

(int)(33.46639 * 1000000) returns 33466389
^^^^^

, чтобы преобразовать результат в тип 'int' ... который округляется в большую или меньшую сторону от целочисленного типа при умножении и последующем преобразовании в 'int' .... не полагайтесь на числа с плавающей запятой, чтобы быть достаточно точным ... Скит опубликовал отличное введение на его сайте здесь и здесь ...

-1
ответ дан 30 November 2019 в 06:59
поделиться

Причина в том, что 33,46639 будет представлено как нечто немного меньшее, чем это число.

Умножение на 1000000 даст вам 33466389,99999999.

Приведение типов с использованием (int) тогда просто вернет целую часть (33466389).

Если вам нужен «правильный» номер, попробуйте round () перед приведением типа.

2
ответ дан 30 November 2019 в 06:59
поделиться

Двойная точность не является точной, поэтому внутри 33.46639 фактически хранится как 33.466389

Изменить: как сказал Ричард, это данные с плавающей запятой (хранятся в двоичном формате в конечном наборе битов), так что это не совсем то) ....

5
ответ дан 30 November 2019 в 06:59
поделиться

В конце 1994 года был канун Нового года. Энди Гроув, генеральный директор Intel, выходил отличным годом, учитывая, что процессор Pentium вышел и стал большим ударить. Итак, он вошел в бар и заказал двойную порцию Johnnie Walker Green Label.

Бармен подал его и сказал: «Это будет 20 долларов, сэр».

Гроув положил двадцатидолларовую купюру на прилавок, взглянул на нее на мгновение и сказал: «Оставьте сдачу себе».

http://en.wikipedia.org/wiki/Pentium_FDIV_bug

3
ответ дан 30 November 2019 в 06:59
поделиться

Потому что 33.46639 не может быть выражено точно конечным числом двоичных цифр. Фактический результат 33,46639 * 1000000: 33466389,9999999962747097015380859375. Приведение усекает его до 33466389.

1
ответ дан 30 November 2019 в 06:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: