Числовые типы с плавающей запятой (справочник по C#)
Числовые типы с плавающей запятой представляют действительные числа. Все числовые типы с плавающей запятой являются типами значений. Они также представляют собой простые типы и могут быть инициализированы литералами. Все числовые типы с плавающей запятой поддерживают арифметические операторы, а также операторы сравнения и равенства.
Характеристики типов с плавающей запятой
C# поддерживает следующие предварительно определенные типы с плавающей запятой:
| Ключевое слово или тип C# | Приблизительный диапазон значений | Точность | Размер | Тип .NET |
|---|---|---|---|---|
| float | От ±1,5 x 10 −45 до ±3,4 x 10 38 | 6–9 цифр | 4 байта | System.Single |
| double | от ±5,0 × 10 −324 до ±1,7 × 10 308 | 15–17 цифр | 8 байт | System.Double |
| decimal | от ±1,0 x 10 -28 до ±7,9228 x 10 28 | 28-29 знаков | 16 байт | System.Decimal |
В приведенной выше таблице каждый тип ключевого слова C# из крайнего левого столбца является псевдонимом для соответствующего типа .NET. Они взаимозаменяемые. Например, следующие объявления объявляют переменные одного типа:
double a = 12.3; System.Double b = 12.3;
По умолчанию все типы с плавающей запятой имеют значение 0 . Все типы с плавающей запятой имеют константы MinValue и MaxValue с минимальным и максимальными итоговыми значениями этого типа. Типы float и double также предоставляют константы, обозначающие бесконечные и нечисловые значения. Например, тип double предоставляет следующие константы: Double.NaN, Double.NegativeInfinity и Double.PositiveInfinity.
Тип decimal подходит, если требуемая степень точности определяется числом цифр справа от десятичной запятой. Такие числа обычно используются в финансовых приложениях для денежных сумм (например, 1,00 долл. США), процентных ставок (например, 2,625 %) и т. д. Даже числа, точные только до одной десятичной цифры, точнее обрабатываются типом decimal : 0,1, например, можно в точности представить экземпляром decimal . При этом не существует экземпляра double или float , который точно представляет 0,1. Из-за этой разницы в числовых типах в арифметических вычислениях могут возникать непредвиденные ошибки округления при использовании double или float для десятичных данных. Вы можете использовать double вместо decimal , если оптимизация производительности важнее, чем обеспечение точности. Но любая разница в производительности останется незамеченной для всех приложений, кроме самых требовательных к вычислениям. Еще одна возможная причина, по которой следует избегать decimal , — это минимальные требования к хранилищу. Например, ML.NET использует float , так как разница между 4 байтами и 16 байтами суммируется для очень больших наборов данных. Для получения дополнительной информации см. System.Decimal.
В одном и том же выражении можно сочетать и целочисленные типы, и типы float и double . В этом случае целочисленные типы неявно преобразуются в один из типов с плавающей запятой. При необходимости тип float неявно преобразуется в double . Выражение вычисляется следующим образом.
- Если в выражении есть тип double , оно оценивается как double или bool в реляционных сравнениях или сравнениях на равенство.
- Если в выражении нет типа double , оно оценивается как float или bool в реляционных сравнениях или сравнениях на равенство.
Можно также смешивать целочисленные типы и тип decimal в выражении. В этом случае целочисленные типы неявно преобразуются в тип decimal , а выражение вычисляется как decimal или bool в реляционных сравнениях и сравнениях на равенство.
Тип decimal нельзя смешивать с типами float и double в выражении. В этом случае, если требуется выполнить арифметические операции или операции сравнения или равенства, необходимо явно преобразовать операнды из типа или в тип decimal , как показано в следующем примере:
double a = 1.0; decimal b = 2.1m; Console.WriteLine(a + (double)b); Console.WriteLine((decimal)a + b);
Можно использовать строки стандартных числовых форматов или строки пользовательских числовых форматов для форматирования значения с плавающей запятой.
Вещественные литералы
Тип реального литерала определяется его суффиксом следующим образом:
- Литерал без суффикса или с суффиксом d или D имеет тип double .
- Литерал с суффиксом f или F имеет тип float .
- Литерал с суффиксом m или M имеет тип decimal .
В приведенном ниже коде показан пример каждого из них.
double d = 3D; d = 4d; d = 3.934_001; float f = 3_000.5F; f = 5.4f; decimal myMoney = 3_000.5m; myMoney = 400.75M;
В предыдущем примере также показано использование _ в качестве разделителя цифр. Цифровой разделитель можно использовать со всеми видами числовых литералов.
Можно также использовать экспоненциальное представление, то есть указать экспоненту вещественного литерала, как показано в следующем примере:
double d = 0.42e2; Console.WriteLine(d); // output 42 float f = 134.45E-2f; Console.WriteLine(f); // output: 1.3445 decimal m = 1.5E6m; Console.WriteLine(m); // output: 1500000
Преобразования
Существует только одно неявное преобразование между числовыми типами с плавающей запятой: из float в double . Однако можно преобразовать любой тип с плавающей запятой в любой другой тип с плавающей запятой с помощьюявного приведения. Для получения дополнительной информации см. статью Встроенные числовые преобразования.
Спецификация языка C#
Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:
- Типы с плавающей запятой
- Тип decimal
- Вещественные литералы
См. также
- справочник по C#
- Типы значений
- Целочисленные типы
- Строки стандартных числовых форматов
- Числовые значения в .NET
- System.Numerics.Complex
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Можно ли сравнивать float с нулем?
Все мы знаем, что к float нельзя (точнее не рекомендуется) применять операцию == . Почему — думаю сами знаете. Но что насчет сравнения с 0? То есть, допустим, у нас есть какая-то переменная, проинициализированная нулем при создание, а далее, возможно, что ей будет присвоено какое-то значение, а может и не будет. Соответственно, если значение переменной равно нулю — то она не была проинициализирована. Так как при инициализации нулем все биты в переменной будут выставлены в 0, то я не вижу причин почему бы не сравнивать float (в данном случае) с нулем. Так ли это?
Отслеживать
13.7k 12 12 золотых знаков 43 43 серебряных знака 75 75 бронзовых знаков
задан 6 ноя 2018 в 16:21
Andrej Levkovitch Andrej Levkovitch
8,047 2 2 золотых знака 19 19 серебряных знаков 46 46 бронзовых знаков
По большому счету, применять сравнение на равенство с инициализатором (было изменено значение или нет) можно для любого значения, лишь бы сам инициализатор выглядел точно так же 🙂 — в том смысле, что битовое представление будет одинаковым.
6 ноя 2018 в 16:26
Тогда уж Nan какой-нибудь использовать, а не 0 . Или вовсе std::optional , если нужно отличать наличие значения.
7 ноя 2018 в 15:21
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Если известно, что число представлено точно, а именно:
- Нет никакой вычислительной погрешности
- Константа сама представима в соответствующем типе без погрешности
то сравнивать на равенство можно.
В остальных случаях сравнение нежелательно и может привести к неправильному результату.
Отслеживать
ответ дан 6 ноя 2018 в 16:55
123k 24 24 золотых знака 126 126 серебряных знаков 303 303 бронзовых знака
Не рекомендуется сравнивать вычисленный float на равенство с нулем.
Не рекомендуется сравнивать никакой float, ни вычисленный, ни константный на равенство с нулем (и на равенство двух float между собой).
Для константного float сравнение будет работать правильно, но это не общий случай.
Предположим есть код.
float n=0; float a1; float a2; //здесь a1 и a2 получили какие-то значения, //возможно пришедшие из внешнего мира (например считанные с АЦП) float delta=a1-a2; if(delta==n) < //do something1 >else < //do something2 >
Когда вычисляется разность delta a1 и a2 могут быть равны с точностью до точности типа float.
Но разность будет не равна нулю и соответственно, сравнение на равенство нулю не пройдет.
И алгоритм пойдет по другой ветке.
В качестве delta может быть не простая разность, а сколь угодно сложные вычисления.
В которых будут и ошибки округления, которые дадут +-1 к точности float.
Поэтому не рекомендуется.
Для двух констант, конечно, это будет работать.
Причем и для ненулевых констант тоже будет работать (на одной и той же платформе конечно).
float n1=0; float n2=0; if(n1==n2) < //do something1 >else < //do something2 >
Или пример для ненулевых констант:
float n1=1.1; float n2=1.1; if(n1==n2) < //do something1 >else < //do something2 >
Но в общем случае, когда float получен после вычислений, на конце у float будет +-1 точности float.
А может и больше, чем +-1 точности float.
И что такое «+-1 точности float» — это какой-то необщепринятый термин
Что-то я не помню, какой для этого есть общепринятый термин.
Может быть «машинный эпсилон» это термин для этого, то есть константа FLT_EPSILON из float.h.
А может быть FLT_MIN это термин для этого.
Наверное все-таки FLT_EPSILON.
Возможная подпрограмма сравнения на равенство для float (если сделать из нее шаблон, то подойдет и для других форматов с плавающей точкой):
bool compare_fl_point(float a1, float a2, float delta=FLT_EPSILON)< float delta1=a1-a2; if(delta1<0) delta1=-delta1; if(delta1>delta) return false; else return true; >
В качестве параметра delta надо выбирать точность вычислений в данной задаче с учетом точности исходных данных и точности собственно вычислений на данной платформе.
Обычно рекомендуется, чтобы точность собственно вычислений на данной платформе превосходила точность входных данных как минимум на порядок.
EPSILON работает несколько иначе – Kromster 1 час назад
Эпсилон здесь только для примера в качестве дефолтного значения.
Более того, сравнивать с эпсилоном бессмысленно, так как эпсилон (по определению) всегда меньше или равен любому float числу.
На месте эпсилона должна быть точность входных данных в данной конкретной задаче.
Обычно точность вычислений выбирают так, чтобы она была как минимум в 10 раз выше, чем точность входных данных.
А вообще-то нужно погуглить этот вопрос.
Тут двух мнений быть не может, есть правила, написанные разработчиками стандарта на float.
Там однозначно говорится, как надо сравнивать float на равенство.
Я погуглил, но сходу выпало только такие же безответственные базары разработчиков на форумах, как и здесь.
Должен быть стандарт, в котором все это прописано.
Можно еще попробовать у Кнута посмотреть, может быть у него есть.
А вот, нашел что-то похожее на статью по теме:
Там есть и про сравнение float на равенство.
И даже отсылка к какой-то импортной статье.
Решил провести вычислительный эксперимент, чтобы посмотреть, как появляются ошибки округления float.
Для этого написал программу, проверяющую известное тождество sin(x)^2+cos(x)^2=1;
Как сравнить тип данных double/float в условии?
Пишу:
if($arr[‘P’] == 0.5)
не работает. не попадает в выборку данный массив. как правильно сравнивать подобный тип данных и с чем может быть связана проблема?
UPD:
Как оказалось, проблема не в этом, а в невозможности сравнивать сразу 3 условия, если сравниваю любые другие два, то все работает. Не понимаю, в чем дело.
- Вопрос задан более трёх лет назад
- 5672 просмотра
Комментировать
Решения вопроса 1
gelirgwenn @gelirgwenn
Вы некорректно сравниваете числа типа float. Все числа хранятся в двоичном представлении на компьютере, так уж заведено, выбрана такая система счисления, потому что информацию в виде нулей и единиц легче обрабатывать и легче делать чипы и т.п.
Так вот некоторые числа не имеют точного представления в двоичной системе. Например, 0,2 имеет вид примерно такой 0,2000000033. Соответственно, при сравнении в лоб, вы не сможете гарантировать корректный результат. Вы можете, к примеру, пробовать сравнивать сравнивать разницу с допустимой абсолютной погрешностью:
if (abs($x – $y) < 0.0001) < // Do something. >
Недостаток данного метода описан здесь, а также другие способы сравнения.
Я бы вам рекомендовал перевести float в целое число или строку. В первом случае вы будете сравнивать два целых числа и у вас не будет проблем, во втором — с помощью функции number_format и заданной точности вы преобразуете число в строку, а далее можете сравнивать строки, содержащие числа, с помощью функции bccomp или аналога:
$x = 0.200000000646456546; $y = 0.200000000676790909; $results = ($x == $y); var_dump($results); // bool(false) $results = bccomp(number_format($x, 5), number_format($y, 5)); var_dump($results); // int(0) - are equal
Как сравнить float с 0
Привет всем!
Есть два числа типа float,
одно содержит 0.50000002607703
другое — 0.50000000000000
Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
Take it easy.
Re: Сравнение float
| От: | Kaa | http://blog.meta.ua/users/kaa/ |
| Дата: | 19.02.02 16:24 | |
| Оценка: |
Здравствуйте Yuri, Вы писали:
Y>Привет всем!
Y>Есть два числа типа float,
Y>одно содержит 0.50000002607703
Y>другое — 0.50000000000000
Y>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
Первое, что приходит в голову — умножить на 100 (на 10 в степени кол-ва нуждных тебе разрядов, в этом случае — 2). и отбросить дробную часть, и сравнить. Или, после умножения вычесть меньшее из большего, и сравнить разность. Если она меньше единицы — все хорошо, это оно.
Алексей Кирдин
Re[2]: Сравнение float
| От: | Sergey |
| Дата: | 19.02.02 16:36 |
| Оценка: |
Здравствуйте Kaa, Вы писали:
Kaa>Здравствуйте Yuri, Вы писали:
Y>>Привет всем!
Y>>Есть два числа типа float,
Y>>одно содержит 0.50000002607703
Y>>другое — 0.50000000000000
Y>>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
Kaa>Первое, что приходит в голову — умножить на 100 (на 10 в степени кол-ва нуждных тебе разрядов, в этом случае — 2). и отбросить дробную часть, и сравнить.
Так делать нельзя. Например, сравни 2.9999999999 и 3.000000000
Kaa>Или, после умножения вычесть меньшее из большего, и сравнить разность. Если она меньше единицы — все хорошо, это оно.
А вот это уже правильно, только умножать незачем — вычесть, сравнить с допустимой ошибкой.
Одним из 33 полных кавалеров ордена «За заслуги перед Отечеством» является Геннадий Хазанов.
Re: Сравнение float
| От: | Кодт |
| Дата: | 19.02.02 16:36 |
| Оценка: |
Здравствуйте Yuri, Вы писали:
Y>Привет всем!
Y>Есть два числа типа float,
Y>одно содержит 0.50000002607703
Y>другое — 0.50000000000000
Y>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
1) округление до 0.01
inline double round_to(double value, double eps) < assert(eps >0); return floor(value/eps + 0.5) * eps; > inline int compare_1(double a, double b, double eps) < double diff = floor(a/eps + 0.5) - floor(b/eps + 0.5); return diff < 0 ? -1 : diff >0 ? +1 : 0; > compare_1(0.5123, 0.5145, 0.01); diff = floor(51.23 + 0.5) - floor(51.45 + 0.5) == 51-51 = 0
2) числа в окрестности +/- 1% считать равными
inline double compare_2(double a, double b, double eps) < double diff = round_to( (a - b) * 2 / (a + b), eps); return diff < 0 ? -1 : diff >0 ? +1 : 0; > compare_2(0.000512, 0.000534, 0.01) diff = round_to( -0.000022 / 0.000522, 0.01 ) = round_to( -0.0421. 0.01 ) = -0.04 compare_2(0.0005123, 0.0005145, 0.01) diff = round_to( -0.0000022 / 0.0005122, 0.01 ) = round_to( -0.00429. 0.01 ) = 0
Перекуём баги на фичи!
Re[3]: Сравнение float
| От: | Kaa | http://blog.meta.ua/users/kaa/ |
| Дата: | 19.02.02 16:42 | |
| Оценка: |
Здравствуйте Sergey, Вы писали:
Чего к словам придираться. Все всё поняли. Дело в алгоритме.
Kaa>>Первое, что приходит в голову — умножить на 100 (на 10 в степени кол-ва нуждных тебе разрядов, в этом случае — 2). и отбросить дробную часть, и сравнить.
S> Так делать нельзя. Например, сравни 2.9999999999 и 3.000000000
299.0 != 300.0, что и требовалось доказать. Что не так? В чем «нельзя»?
Kaa>>Или, после умножения вычесть меньшее из большего, и сравнить разность. Если она меньше единицы — все хорошо, это оно.
S> А вот это уже правильно, только умножать незачем — вычесть, сравнить с допустимой ошибкой.
Можно и не умножать. Тогда погрешность (допустимую ошибку) знать надо.
Алексей Кирдин
Re[4]: Сравнение float
| От: | Sergey |
| Дата: | 19.02.02 16:54 |
| Оценка: |
Здравствуйте Kaa, Вы писали:
Kaa>Здравствуйте Sergey, Вы писали:
Kaa>Чего к словам придираться. Все всё поняли. Дело в алгоритме.
Kaa>>>Первое, что приходит в голову — умножить на 100 (на 10 в степени кол-ва нуждных тебе разрядов, в этом случае — 2). и отбросить дробную часть, и сравнить.
S>> Так делать нельзя. Например, сравни 2.9999999999 и 3.000000000
Kaa>299.0 != 300.0, что и требовалось доказать. Что не так? В чем «нельзя»?
Ты всерьез полагаешь, что человеку надо именно это — два числа, отличающиещиеся на 0.0е-10, считать разными? Если да, то можно просто битмаской лишнее прихлопнуть (сколько там двоичных знаков, сразу и не соображу) и сравнивать — будет типа очень быстро
Kaa>>>Или, после умножения вычесть меньшее из большего, и сравнить разность. Если она меньше единицы — все хорошо, это оно.
S>> А вот это уже правильно, только умножать незачем — вычесть, сравнить с допустимой ошибкой.
Kaa>Можно и не умножать. Тогда погрешность (допустимую ошибку) знать надо.
Kaa>С уважением
Одним из 33 полных кавалеров ордена «За заслуги перед Отечеством» является Геннадий Хазанов.
Re: Сравнение float
| От: | Курилка | http://kirya.narod.ru/ |
| Дата: | 19.02.02 17:04 | |
| Оценка: | +1 | |
Здравствуйте Yuri, Вы писали:
Y>Привет всем!
Y>Есть два числа типа float,
Y>одно содержит 0.50000002607703
Y>другое — 0.50000000000000
Y>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
Re[5]: Сравнение float
| От: | Kaa | http://blog.meta.ua/users/kaa/ |
| Дата: | 19.02.02 17:11 | |
| Оценка: |
Здравствуйте Sergey, Вы писали:
S> Ты всерьез полагаешь, что человеку надо именно это — два числа, отличающиещиеся на 0.0е-10, считать разными? Если да, то можно просто битмаской лишнее прихлопнуть (сколько там двоичных знаков, сразу и не соображу) и сравнивать — будет типа очень быстро
Вопрос перечитай, что-ли. Ему надо, в твоих терминах, отождествить 2 числа с одинаковыми первыми тремя разрядами при равным показателем степени в стандартной заприси числа.
Алексей Кирдин
Re[6]: Сравнение float
| От: | Sergey |
| Дата: | 20.02.02 08:04 |
| Оценка: |
Здравствуйте Kaa, Вы писали:
Kaa>Здравствуйте Sergey, Вы писали:
S>> Ты всерьез полагаешь, что человеку надо именно это — два числа, отличающиещиеся на 0.0е-10, считать разными? Если да, то можно просто битмаской лишнее прихлопнуть (сколько там двоичных знаков, сразу и не соображу) и сравнивать — будет типа очень быстро
Kaa>Вопрос перечитай, что-ли. Ему надо, в твоих терминах, отождествить 2 числа с одинаковыми первыми тремя разрядами при равным показателем степени в стандартной заприси числа.
Перечитал. По вопросу совершенно непонятно, что ж ему все-таки надо. Так что если ему это еще надо, пусть задает вопрос по новой
Одним из 33 полных кавалеров ордена «За заслуги перед Отечеством» является Геннадий Хазанов.
Re[2]: Сравнение float
| От: | Kaa | http://blog.meta.ua/users/kaa/ |
| Дата: | 20.02.02 13:18 | |
| Оценка: |
Здравствуйте Курилка, Вы писали:
К>Здравствуйте Yuri, Вы писали:
Y>>Привет всем!
Y>>Есть два числа типа float,
Y>>одно содержит 0.50000002607703
Y>>другое — 0.50000000000000
Y>>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
К>я дак делаю fabs(val1-val2) К>где delta — необходимая точность
Это немного не то. Вот тебе пример:
2.99092 -> 2.99 != 3.00 -> 3.00, хотя при этом |2.99092 — 3.00| < 0.01
Короче говоря, требуется совпадение разрядов, а не просто их близость на числовой прямой.
Алексей Кирдин
Re[3]: Сравнение float
| От: | Курилка | http://kirya.narod.ru/ |
| Дата: | 20.02.02 13:38 | |
| Оценка: |
Здравствуйте Kaa, Вы писали:
Kaa>Здравствуйте Курилка, Вы писали:
К>>Здравствуйте Yuri, Вы писали:
Y>>>Привет всем!
Y>>>Есть два числа типа float,
Y>>>одно содержит 0.50000002607703
Y>>>другое — 0.50000000000000
Y>>>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
К>>я дак делаю fabs(val1-val2) К>>где delta — необходимая точность
Kaa>Это немного не то. Вот тебе пример:
Kaa>2.99092 -> 2.99 != 3.00 -> 3.00, хотя при этом |2.99092 — 3.00| < 0.01
Kaa>Короче говоря, требуется совпадение разрядов, а не просто их близость на числовой прямой.
И кому такое сравнение нужно. Стесняюсь спросить.
тогда и 2.9901 будет равно 3.0099?
по-моему для нормальной задачи это бред
Re[4]: Сравнение float
| От: | Kaa | http://blog.meta.ua/users/kaa/ |
| Дата: | 20.02.02 13:45 | |
| Оценка: | 1 (1) | |
Здравствуйте Курилка, Вы писали:
Y>>>>Привет всем!
Y>>>>Есть два числа типа float,
Y>>>>одно содержит 0.50000002607703
Y>>>>другое — 0.50000000000000
Y>>>>Как мне их сравнить, так чтобы в сравнении участвовали только две цифры после запятой
Это видел?
Kaa>>Это немного не то. Вот тебе пример:
Kaa>>2.99092 -> 2.99 != 3.00 -> 3.00, хотя при этом |2.99092 — 3.00| < 0.01
Kaa>>Короче говоря, требуется совпадение разрядов, а не просто их близость на числовой прямой.
К>И кому такое сравнение нужно. Стесняюсь спросить.
Ему нужно, спрашивающему.
К>тогда и 2.9901 будет равно 3.0099?
Когда — «тогда». Отождествляются только чиса с первыми тремя разрядами. В твоем примере это не так. Разряды различаются. Так, напимер, можно сравнивать деньги: целые — рубли, дробные — копейки. Без большой точности. Это, ты считаешь, не реальная задача? )
Алексей Кирдин
Re[5]: Сравнение float
| От: | Курилка | http://kirya.narod.ru/ |
| Дата: | 20.02.02 13:51 | |
| Оценка: |
Здравствуйте Kaa, Вы писали:
К>>тогда и 2.9901 будет равно 3.0099?
Kaa>Когда — «тогда». Отождествляются только чиса с первыми тремя разрядами. В твоем примере это не так. Разряды различаются.
сорри, я имел в виду 2.9999 != 3.00
вечно пишу совсем не то, что думаю
Kaa>Так, напимер, можно сравнивать деньги: целые — рубли, дробные — копейки. Без большой точности. Это, ты считаешь, не реальная задача? )
наверно ты прав, хотя на мой взгляд это тоже спорно, как деньги округлять.
Re[6]: Сравнение float
| От: | Кодт |
| Дата: | 21.02.02 10:16 |
| Оценка: |
Здравствуйте Курилка, Вы писали:
К>Здравствуйте Kaa, Вы писали:
К>>>тогда и 2.9901 будет равно 3.0099?
Kaa>>Когда — «тогда». Отождествляются только чиса с первыми тремя разрядами. В твоем примере это не так. Разряды различаются.
К>сорри, я имел в виду 2.9999 != 3.00
К>вечно пишу совсем не то, что думаю
Kaa>>Так, напимер, можно сравнивать деньги: целые — рубли, дробные — копейки. Без большой точности. Это, ты считаешь, не реальная задача? )
К>наверно ты прав, хотя на мой взгляд это тоже спорно, как деньги округлять.