float неверное преобразование / float неожиданное поведение - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь сосредоточиться на поведении с плавающей точкой (в C #).Я обратил внимание на проблему точности с плавающей запятой .Я хочу преобразовать строку с плавающей запятой в число с плавающей запятой, добавить + 1 к ней и преобразовать ее обратно в строку.Ввод может быть с (не более 5 десятичных разрядов) или без десятичных разрядов, каждый раз это отличается.Выходными данными должны быть снова полная нотация (без научной нотации, например: 2.017002E + 09F)

Кажется, что она работает правильно с десятичным преобразованием.

Любые предложения для получения наилучшей практики, чтобы получитьэто работает с поплавком?

var inputDecimalStr = "2017002005"; //2017002005.55 has the same result for the float conversion
float floatRegNr = 0;
float.TryParse(inputDecimalStr, out floatRegNr); // somehow this converts to 2.017002E+09
decimal test1 = decimal.Parse(inputDecimalStr); // this seems to work
float test2 = Convert.ToSingle(test1); // somehow this converts to 2.017002E+09
float test3 = Single.Parse(inputDecimalStr, NumberStyles.Float, CultureInfo.InvariantCulture);
float test4 = 2017002005F;
float test5 = 2.017002E+09F;
float test6 = 2.017002005E+09F;
double test7 = 234423.33D;

//this works ok
test5.ToString("0." + new string('#', 339));
test1.ToString();

1 2

1 Ответ

0 голосов
/ 22 ноября 2018

Если вы используете этот инструмент, который показывает двоичное представление числа с плавающей запятой , вы получите, что 2017002005 представляется как 0x4ef07204, что в переводе на десятичную форму становится 2017001984 (ошибка21 из преобразования).

Если вы измените младший значащий бит числа (т.е. минимальное изменение, которое можно зарегистрировать), вы получите 0x4ef07205, что представляет 2017002112 (на 107 больше, чем 2017002005 + 1.

Если этот уровень детализации важен, вы можете использовать арифметику с фиксированной запятой.Так как вы хотите только добавить 1, разбить число на целые и десятичные части, добавить 1 к целой части и затем преобразовать обратноСтруну каждую часть отдельно.

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