Что делает компилятор, когда он конвертирует переменную с плавающей точкой в ​​целочисленную переменную? - PullRequest
2 голосов
/ 14 октября 2011

Что делает компилятор?Цель состоит в том, чтобы получить число после точки в виде целого числа.Я сделал это так:

float a = 0;
cin >> a;

int b = (a - (int)a)*10;

Теперь моя проблема заключается в следующем: когда я вхожу, например, 3.2, я получаю 2, что я и хочу.Это также работает с .4, .5 и .7.но когда я ввожу, например, 2.3, я получаю 2. Для 2.7 я получаю 6 и так далее.Но когда я делаю это без переменных, например:

(2.3 - (int)2.3)*10;

, я получаю правильный результат.

Я не мог понять, что делает компилятор.Я всегда думал, что когда я приведу число с плавающей точкой к целому числу, то оно просто срезает точку.Это то, что на самом деле делает компилятор, когда я использую постоянные числа.Однако когда я использую переменные, компилятор уменьшает некоторые из них, но не все.

Ответы [ 4 ]

3 голосов
/ 14 октября 2011

Скорее всего, у вас нет проблем с компилятором, но с тем фактом, что числа с плавающей точкой не могут быть точно представлены на двоичном компьютере.

Итак, когда вы делаете:1005 * .. что на самом деле может храниться в компьютере:

2.6999999999999999

Это очень известная характеристика с плавающей запятой на двоичных компьютерах.На SO много сообщений, где это обсуждается.

2 голосов
/ 14 октября 2011

По сути, проблема заключается в том, что двоичные значения имеют «бесконечно повторяющиеся» значения, чем база 10.Например.1/10 в десятичном виде - это 0,1, в двоичном - 0,000110011001100110011001100 ... Проблема вызвана тем, что с плавающей запятой не может правильно удерживать 2,3, потому что это бесконечное число двоичных цифр, но оно приблизительно соответствует, вероятно, 2,2999999.Для большинства математики это достаточно близко.Но будьте осторожны с усечением.

Одним из решений является округление перед усечением.

int b = (a - (int)(a+.05))*10;

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

1 голос
/ 14 октября 2011

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

0 голосов
/ 14 октября 2011

Почему бы тебе не сделать это так?

b = (a*10)%10;

Мне гораздо проще.

...