@Yxine

Проблема с конвертированием decimal в float?

Код:

using System;
public class Program
{
	public static void Main()
	{
		decimal d = 40350m * 63.96m * 0.09m;
		Console.WriteLine(d);
		string s = "232270.74";
		float f1 = Convert.ToSingle(s);
		Console.WriteLine(f1.ToString("R"));
		float f2 = Convert.ToSingle(s);
		Console.WriteLine(f2.ToString("R"));
	}
}


Результат:

232270.7400
232270.734
232270.734

Вопрос:

Как добиться, чтобы при конвертации во float было таки 232270.74?
  • Вопрос задан
  • 1251 просмотр
Решения вопроса 3
1) Во время преобразования числа с плавающей точкой в целое, дробная часть отбрасывается; никакого округления не производится. Статический класс System.Convert предоставляет методы, которые выполняют преобразования между различными числовыми типами с округлением.

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

    int i1 = 100000001;
    float f = i1;        // Величина сохраняется, точность теряется
    int i2 = (int)f;     // 100000000

3) Ошибки округления вещественных чисел
Типы float и double внутренне представляют числа в двоичной форме. По этой причине точно представляются только числа, которые могут быть выражены в двоичной системе счисления. На практике это означает, что большинство литералов с дробной частью (которые являются десятичными) не будут представлены точно.
Например:

        float tenth = 0.1f;                            // Heточно 0.1
        float one = 1f;
        Console.WriteLine (one - tenth * 10f);        // -1.490116E-08

Именно поэтому типы float и double не подходят для финансовых вычислений. В противоположность им тип decimal работает в десятичной системе счисления и, таким образом, может точно представлять числа, выразимые в десятичной системе (а также в системах счисления с основаниями-множителями 10 — двоичной и пятеричной). Поскольку вещественные литералы являются десятичными, тип decimal может точно представлять такие числа, как 0.1. Тем не менее, ни double, ни decimal не могут точно представить дробную часть, десятичное представление которой является периодическим:

    decimal m = 1M / 6M;    // 0.1666666666666666666666666667M
    double d = 1.0 / 6.0;    // 0.16666666666666666

Это приводит к накапливающимся ошибкам округления:

    decimal notQuiteWholeM = m+m+m+m+m+m;     // 1.0000000000000000000000000002M
    double notQuiteWholeD = d+d+d+d+d+d;     // 0.99999999999999989

которые нарушают работу операций эквивалентности и сравнения:

    Console.WriteLine (notQuiteWholeM == 1M);     // Выводит False
    Console.WriteLine (notQuiteWholeD < 1.0);/    / Выводит True

Андерс Хейлсберг. Язык программирования C#, 4-е издание
Ответ написан
Комментировать
Aquarius-Michael
@Aquarius-Michael
Программист и железячник
Тип Decimal позволяет показать числа абсолютной точности до последней цифры. А вот в float существует такое понятие: точность действительных чисел. Это означает часть чисел надо отбрасывать. Прежде, чем заниматься программированием и прочее, полезно для начала изучить базовую часть, как представлены данные в компьютерах и как приняты в языках программирования. Без знания оных можно напороться на опасные и/или дорогостоящие ошибки.
Если вы хотите выполнять расчёты, где важна точность каждой цифры, то лучше держаться около типов с фиксированной запятой. Это могут быть финансовые и учётные расчёты.
А если игры и прочее моделирование, то подойдут числа с плавающей запятой.
Ответ написан
Комментировать
@Alexander1705
Wikipedia:
Числа одинарной точности с плавающей запятой обеспечивают относительную точность 7-8 десятичных цифр в диапазоне от 10^-38 до примерно 10^38.


P. S. Если бы во float можно было записывать десятичные числа любой точности, зачем тогда, по вашему, нужен decimal?
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы