Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.59/29: Рейтинг темы: голосов - 29, средняя оценка - 4.59
 Аватар для javay
0 / 0 / 0
Регистрация: 07.08.2016
Сообщений: 105

Неточность double и float

27.10.2018, 00:26. Показов 5729. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приведу 2 примера кода:
C#
1
2
3
Int a=10000001;
float b=(float) a;
a=(int)b;  // "a" уже равно не 10000001, а 10000000
C#
1
2
3
4
 
float a=0.1f;
float b=1f;
Console.WriteLine(b-a*10f); // выведется -1.490116E-08
Почему так происходит, и как понять когда такие непонятные фичи с вычислениями могут произойти?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
27.10.2018, 00:26
Ответы с готовыми решениями:

Передача переменной типа double из c# в переменную типа float в SQL
Здравствуйте, имеется проблема с передачей данных из кода c# в бд SQL Имеется переменная типа double, к примеру double newPrice =...

Double = Float = Int
Дамы и господа! Тут "либо я дурак, либо лыжи не едут" © double odds = 6/50; float a = 6 / 50; ...

Конвертировать float в double
Ошибка 2 Не удается неявно преобразовать тип "double" в "float". Существует явное преобразование (возможно, пропущено приведение...

16
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
27.10.2018, 00:59
Цитата Сообщение от javay Посмотреть сообщение
Почему так происходит
По стандарту IEEE 754.
0
Модератор
 Аватар для Curry
5158 / 3482 / 536
Регистрация: 01.06.2013
Сообщений: 7,549
Записей в блоге: 9
27.10.2018, 01:00
Что за тип Int ? А если заменить на int, то у меня 10000001 выдаёт.

В случае чего округлять можно вещественные числа Math.Round(b). (int)b только отбрасывает дробную часть, а не округляет.
1
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
27.10.2018, 01:00
Цитата Сообщение от javay Посмотреть сообщение
как понять когда такие непонятные фичи с вычислениями могут произойти?
Когда число нельзя с абсолютной точностью выразить через различные степени двойки: как положительные, так и отрицательные.
1
 Аватар для ashsvis
923 / 503 / 202
Регистрация: 08.10.2018
Сообщений: 1,553
Записей в блоге: 11
27.10.2018, 09:59
Цитата Сообщение от javay Посмотреть сообщение
непонятные фичи с вычислениями
если хотите точнее, используйте double вместо float, а если хотите ещё точнее -
то используйте decimal для представления вещественных чисел.
1
 Аватар для javay
0 / 0 / 0
Регистрация: 07.08.2016
Сообщений: 105
27.10.2018, 11:52  [ТС]
ashsvis, а зачем вообще вводить типы, которые неточные, это программирование и как я считаю, тут все должно быть точно. Ибо смысл тогда в этих типах
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
27.10.2018, 11:56
C#
1
2
3
4
        int a=10000001;
        float b=(float)a;
        a=(int)b;
        Console.WriteLine(a);
У меня этот код дает корректный результат.

https://habr.com/post/112953/
читайте весь пост, в п. 4.1 есть подпункт про вычитание близких чисел.
1
 Аватар для javay
0 / 0 / 0
Регистрация: 07.08.2016
Сообщений: 105
27.10.2018, 11:58  [ТС]
Да какая там нафиг точность, когда элементарно 1f-0.1f*10f не может высчитаться

Добавлено через 1 минуту
Woldemar89, ну добавьте ещё 2 нолика и не будет,ну описАлся я
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
27.10.2018, 12:01
Цитата Сообщение от javay Посмотреть сообщение
а зачем вообще вводить типы, которые неточные, это программирование и как я считаю, тут все должно быть точно
Вы удивитесь, но в природе ничего не бывает абсолютно точно. Любая физическая величина известна лишь с конечной точностью.
Абсолютная точность - это выдумка человека. Поэтому, если вам нужно считать искусственные величины - например количество чего-либо или деньги - нужно использовать абсолютно точные типы - int, decimal. Если же у вас физические величины - масса, размер - нужно/можно использовать типы с погрешностью - float, double.
1
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
27.10.2018, 12:03
Цитата Сообщение от javay Посмотреть сообщение
а зачем вообще вводить типы, которые неточные, это программирование и как я считаю, тут все должно быть точно. Ибо смысл тогда в этих типах
Смысл в представлении чисел в вычислительной технике.
Есть 8ми, 16ти, 32х, 64х битные регистры процессора.
Нужно в этих регистрах каким то образом хранить десятичные дроби.
Как поступите? Предложите Ваше решение?
Которое по производительности хотя бы близко к используемому?
(хранение знака, порядка, мантиссы и специальные наборы команд процессора для работы с этими числами)?
1
 Аватар для javay
0 / 0 / 0
Регистрация: 07.08.2016
Сообщений: 105
27.10.2018, 12:06  [ТС]
Storm23,
Да какая там нафиг точность, когда элементарно 1f-0.1f*10f не может высчитаться
я пониаю, там 6 знак после запятой неправильно высчитывался, но ни когда же у нас 2+2 ошибки выдавать
0
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
27.10.2018, 12:18
Числа с плавающей запятой
Число половинной точности
Число одинарной точности
Число двойной точности
Число четверной точности

javay, вы используете float (алиас System.Single (single precision)) - число одинарной точности, требуя от него четверной или бесконечной.
Другими словами - прежде чем что-то использовать - прочитайте инструкцию.
Да, это касается даже таких "мелочей" как "элементарные" типы.
1
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
27.10.2018, 12:24
Цитата Сообщение от javay Посмотреть сообщение
я пониаю, там 6 знак после запятой неправильно высчитывался, но ни когда же у нас 2+2 ошибки выдавать
2+2 - всегда будет 4. Никаких ошибок там нет, и быть не может. Потому что это - количественные величины и вы будете для них использовать тип int.
Цитата Сообщение от javay Посмотреть сообщение
я пониаю, там 6 знак после запятой неправильно высчитывался,
Это и есть 6 знак после запятой. Просто у вас школьное понимание запятой. Типы с плавающей запятой потому так и называются, что место запятой - не фиксировано.
Число 10000001f, на самом деле выглядит вот так:
0.10000001e8
И последняя единица выходит за пределы точности float.
1
 Аватар для javay
0 / 0 / 0
Регистрация: 07.08.2016
Сообщений: 105
27.10.2018, 12:32  [ТС]
ну а 1f-0.1f*10f почему тогда не правильно высчитывается, ведь это не такое уж и большое число?
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
27.10.2018, 12:37
Цитата Сообщение от javay Посмотреть сообщение
ну а 1f-0.1f*10f почему тогда не правильно высчитывается, ведь это не такое уж и большое число?
Потому что 0.1 в двоичной системе счисления - бесконечная дробь:
0.000110011(0011)...
Соответственно последние единицы отрезаются из-за конечной точности float. Как результат - число хранится с погрешностью.

PS И кстати не пишите "ошибка", а пишите "погрешность". Это не одно и то же. Никаких ошибок в цифровых процессорах быть не может. Бывают погрешности хранения чисел.
1
TheGreatCornholio
 Аватар для Woldemar89
1255 / 733 / 285
Регистрация: 30.07.2015
Сообщений: 2,408
27.10.2018, 12:44
Цитата Сообщение от javay Посмотреть сообщение
ну а 1f-0.1f*10f почему тогда не правильно высчитывается, ведь это не такое уж и большое число?
C#
1
2
3
        float c=0.1f;
        float d=1.0f;
        Console.WriteLine((d-c*10.0f).ToString("###0.0000000000000000000000"));
Результат
-0.0000000149011600000000 //точность float 7 знаков, погрешность находиться за пределами 7ми знаков
1
 Аватар для ashsvis
923 / 503 / 202
Регистрация: 08.10.2018
Сообщений: 1,553
Записей в блоге: 11
27.10.2018, 13:37
Цитата Сообщение от javay Посмотреть сообщение
а зачем вообще вводить типы, которые неточные
дело в том, что сначала компьютеры (и процессоры в них) были не такие мощные, как сейчас,
поэтому сначала (исторически) появился тип float (формат представления чисел с плавающей
запятой, занимающий 4 байта). Тип double (по самому названию - двойной точности, занимает
8 байт). А процессора сначала были 8-ми битными (1 байт данных), потом 16-ти битные и так далее.
И поэтому скорость вычисления операций с 8-ми байтными числами на процессорах с 2-мя байтами
(допустим) занимало много времени. А для расчётов попроще типа float вполне хватало.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.10.2018, 13:37
Помогаю со студенческими работами здесь

Преобразование типа double во float
Добрый день! Возникла такая проблема. Написал в 1 строчке то, как мне нужно сделать и, конечно же, мне выдает ошибку о том, что не удается...

Не выходит преобразование double в float
Не знаю что сделать, перепробовал все что мог.

Перевод строки в double или float
string cz = "1.1632"; Подскажите как правильно перевести?

Число байт для double/float
Пишу задачи на типизированные файлы. Необходимо использовать переменную типа Double или Float дли зписи средней оценки стулента. Скажите,...

Невозможно преобразовать тип double в float
using System; namespace Preobra_type { class MainClass { public static void Main(string args) { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru