согласитесь, что приведение от float к double — это в некотором смысле повышение точности переменной, и от повышения точности не должно возникать каких то погрешностей. а они возникают, что очень странно.
а про представление в 2м виде — да мне все равно как оно там хранится,
у меня равенство (decimal)0.001f == (decimal)(double)0.001f не выполняется
(здесь приведение к decimal выполняет роль объективного сравнения), вот в чем жесть.
Здравствуйте, barn_czn, Вы писали:
_>Собственно сабж. _>Народ, может мне ктонить ответить мочему так работает приведение. _>У меня есть предположение что шум появляется из-за того что размер float меньше размера double, и оставшаяся часть мантисы заполняется шумом. _>Вопрос — почему шумом а не нулями?
Блин, ну внесите уже этот вопрос в FAQ — ей-богу, каждый месяц его задают!
Здравствуйте, barn_czn, Вы писали:
_>согласитесь, что приведение от float к double — это в некотором смысле повышение точности переменной, и от повышения точности не должно возникать каких то погрешностей. а они возникают, что очень странно.
_>а про представление в 2м виде — да мне все равно как оно там хранится,
Хранит железо, ему не поровну. Вообще под видом 0.001f хранится несколько другое число:
> 0.001f;;
val it : float32 = 0.00100000005f
_>у меня равенство (decimal)0.001f == (decimal)(double)0.001f не выполняется _>(здесь приведение к decimal выполняет роль объективного сравнения), вот в чем жесть.
Жесть в том, что это пишет разработчик с минимум семилетним стажем (судя по профилю)
Здравствуйте, barn_czn, Вы писали:
_>>>у меня равенство (decimal)0.001f == (decimal)(double)0.001f не выполняется _>>>(здесь приведение к decimal выполняет роль объективного сравнения), вот в чем жесть.
S>>Жесть в том, что это пишет разработчик с минимум семилетним стажем (судя по профилю)
_>ага, жесть. только вот ответа так и нет. и Вы его не дали, хотя наверняка считаете себя профессионалом ))
Ответ был неоднократно Вам дан (не мной), но судя по тому что тема продолжается, этот ответ Вас не устраивает. Вы сравниваете числа, полученные разными способами, но все равно настойчиво продолжаете упираться что не выполняется равенство, будто от этого что-то изменится в представлениях чисел.
Еще раз: нет способа представить 0.001 в float формате, потому вместо него хранится некоторое число, которое в десятичном виде с float- точностью представимо как 0.00100000005f. Но лучший способ представить такое число с помощью double-а в десятичном виде выглядит как 0.0010000000474974513. Формально это другое число.
Здравствуйте, SaZ, Вы писали:
SaZ>Здравствуйте, samius, Вы писали:
S>>Жесть в том, что это пишет разработчик с минимум семилетним стажем (судя по профилю)
SaZ>Ну не сталкивался он за 7 лет с необходимостью сравнивать числа с плавающей точкой. Только вот его опыт приводит к излишней самоуверенности. SaZ>Лично я сталкивался с этим только в 1-м реальном проекте (ну и плюс лабы по мат. моделированию). Правда опыт у меня в пару-тройку раз меньше.
ээ, ребята, тока не на кол ))
о какой самоуверенности вы говорите? идет дискуссия, я выдвигаю аргументы. надо либо конструктивно учавствовать либо отойти в сторону.
не надо самоутверждатся на незнании других, и тем более переходить на личное типа " фу лох, ты незнаеш такой простой вещи..".
_>>у меня равенство (decimal)0.001f == (decimal)(double)0.001f не выполняется _>>(здесь приведение к decimal выполняет роль объективного сравнения), вот в чем жесть.
S>Жесть в том, что это пишет разработчик с минимум семилетним стажем (судя по профилю)
ага, жесть. только вот ответа так и нет. и Вы его не дали, хотя наверняка считаете себя профессионалом ))
Здравствуйте, barn_czn, Вы писали:
_>Собственно сабж. _>Народ, может мне ктонить ответить мочему так работает приведение. _>У меня есть предположение что шум появляется из-за того что размер float меньше размера double, и оставшаяся часть мантисы заполняется шумом. _>Вопрос — почему шумом а не нулями?
и объявила: "Чтоб представить число с половинной точностью, нужно взять из этого ряда подряд 10 чисел и сложить некоторые из них так, чтоб сумма была максимально близкой к представляемому числу. Минимум будет <тра-ля-ля>, а максимум <тра-ля-ля>." И тоже самое рассказала про одинарную и двойную точность, а потом и про расширенную заикнулась отдельно. Ну она кнешно объяснила как этот ряд делается и всякие сухости в итоге, но с такой таблицей было сразу многое понятно.
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[3]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, barn_czn, Вы писали:
_>>>Народ, может мне ктонить ответить мочему так работает приведение. _>>>У меня есть предположение что шум появляется из-за того что размер float меньше размера double, и оставшаяся часть мантисы заполняется шумом. _>>>Вопрос — почему шумом а не нулями? LVV>>Дык попробуй сам вручную перевести 0.001 из десятичной в двоичную. А потом обратно. И помедитируй над результатами. _>Не понимаю. _>0.001 = 1 * 10^-3, т.е. _>Мантиса = 000...0001 _>Степень = +1 (знак "-") 000..100 _>Ну как так, кол-во нулей не важно. _>Где здесь бесконечная периодическая двоичная запись?
По сути — в представлении double и float основание степени не десять как у вы считаете ("0.001 = 1 * 10^-3") а два Попробуйте отыскать такие q и M что бы 0.001 = M * 2 ^ q.
А вот в Systen.Decimal одна тысячная представима как нельзя лучше. Там основание 10.
Help will always be given at Hogwarts to those who ask for it.
Re[5]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, barn_czn, Вы писали:
V>>В принципе при сравнении двух дробных чисел нельзя использовать явную проверку на равенство, нужно проверять V>>является ли модуль разности менее какой-либо точности, определенной для данной задачи.
_>Про сравнение согласен, если в коде есть сравнение двух плавающих — тут явно чтото не так.
Оба утверждения неверны. Что "не так" в следующем сравнении:
var d1 = 2.2 / 3.3;
var d2 = 4.4 / 6.6;
Debug.Assert(d1 == d2, "d1 == d2");
Сравнивать нужно аккуратно, да, понимая что делаешь. Но можно.
Help will always be given at Hogwarts to those who ask for it.
Собственно сабж.
Народ, может мне ктонить ответить мочему так работает приведение.
У меня есть предположение что шум появляется из-за того что размер float меньше размера double, и оставшаяся часть мантисы заполняется шумом.
Вопрос — почему шумом а не нулями?
Здравствуйте, barn_czn, Вы писали:
_>Собственно сабж. _>Народ, может мне ктонить ответить мочему так работает приведение. _>У меня есть предположение что шум появляется из-за того что размер float меньше размера double, и оставшаяся часть мантисы заполняется шумом. _>Вопрос — почему шумом а не нулями?
попытайся записать 1/1000 в двоичной системе исчесления. И почитай википедию
Здравствуйте, barn_czn, Вы писали:
_>Собственно сабж. _>Народ, может мне ктонить ответить мочему так работает приведение. _>У меня есть предположение что шум появляется из-за того что размер float меньше размера double, и оставшаяся часть мантисы заполняется шумом. _>Вопрос — почему шумом а не нулями?
Дык попробуй сам вручную перевести 0.001 из десятичной в двоичную. А потом обратно. И помедитируй над результатами.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, LaptevVV, Вы писали:
LVV>Здравствуйте, barn_czn, Вы писали:
_>>Собственно сабж. _>>Народ, может мне ктонить ответить мочему так работает приведение. _>>У меня есть предположение что шум появляется из-за того что размер float меньше размера double, и оставшаяся часть мантисы заполняется шумом. _>>Вопрос — почему шумом а не нулями? LVV>Дык попробуй сам вручную перевести 0.001 из десятичной в двоичную. А потом обратно. И помедитируй над результатами.
Не понимаю.
0.001 = 1 * 10^-3, т.е.
Мантиса = 000...0001
Степень = +1 (знак "-") 000..100
Ну как так, кол-во нулей не важно.
Где здесь бесконечная периодическая двоичная запись?
Re[2]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, barn_czn, Вы писали:
_>>Собственно сабж. _>>Народ, может мне ктонить ответить мочему так работает приведение. _>>У меня есть предположение что шум появляется из-за того что размер float меньше размера double, и оставшаяся часть мантисы заполняется шумом. _>>Вопрос — почему шумом а не нулями?
А>попытайся записать 1/1000 в двоичной системе исчесления. А>И почитай википедию
В википедии говорится о какой то периодической двоичной записи для 0.1 Откуда она берется — не понимаю.
Но дело ведь не в представлении таких чисел, а преобразовании типов.
Создать переменную float f = 0.001f я могу, double d = 0.001 — тоже могу. Какова ж черта d != (double)f ?
Здравствуйте, barn_czn, Вы писали:
_>Собственно сабж. _>Народ, может мне ктонить ответить мочему так работает приведение. _>У меня есть предположение что шум появляется из-за того что размер float меньше размера double, и оставшаяся часть мантисы заполняется шумом. _>Вопрос — почему шумом а не нулями?
Все зависит от компилятора!!! При приведении типа часть компиляторов просто копирует кусок памяти меньшего размера (float) в больший (doudle). Все что было больше размера меньшего операнда остается. Собственно если сначала обнулить doudle то все будет как надо.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, barn_czn, Вы писали:
А>Все зависит от компилятора!!! При приведении типа часть компиляторов просто копирует кусок памяти меньшего размера (float) в больший (doudle). Все что было больше размера меньшего операнда остается.
И порядок float-а плавно переходит в мантиссу double-а... Браво!
A> Собственно если сначала обнулить doudle то все будет как надо.
И на каких компиляторах работает "как надо"?
Здравствуйте, barn_czn, Вы писали:
_>Но дело ведь не в представлении таких чисел, а преобразовании типов. _>Создать переменную float f = 0.001f я могу, double d = 0.001 — тоже могу. Какова ж черта d != (double)f ?
Честно, после того когда давненько прочитал стандарты IEEE, меня такое не удивляет.
p.s.
В принципе при сравнении двух дробных чисел нельзя использовать явную проверку на равенство, нужно проверять
является ли модуль разности менее какой-либо точности, определенной для данной задачи.
Re[4]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, venicum, Вы писали:
V>Здравствуйте, barn_czn, Вы писали:
_>>Но дело ведь не в представлении таких чисел, а преобразовании типов. _>>Создать переменную float f = 0.001f я могу, double d = 0.001 — тоже могу. Какова ж черта d != (double)f ?
V>Честно, после того когда давненько прочитал стандарты IEEE, меня такое не удивляет. V>p.s. V>В принципе при сравнении двух дробных чисел нельзя использовать явную проверку на равенство, нужно проверять V>является ли модуль разности менее какой-либо точности, определенной для данной задачи.
Про сравнение согласен, если в коде есть сравнение двух плавающих — тут явно чтото не так.
Я просто довел реальную ситуацию до абсурда, чтобы пример проще был.
А реальная проблема вот в чем. Некий метод делает вычисления на float-ах. Далее результат этого метода попадает в другой метод где уже вычисления ведутся на double, т.е. входные данные — аргумент double. А в результате такова кривого приведения получается что входные данные с ошибкой пришли.
И это мне очень не нравится. Победил пока это двойным приведением (double)(decimal)f. Костыль конечно, но работает.
Re[3]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, samius, Вы писали:
S>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, barn_czn, Вы писали:
А>>Все зависит от компилятора!!! При приведении типа часть компиляторов просто копирует кусок памяти меньшего размера (float) в больший (doudle). Все что было больше размера меньшего операнда остается. S>И порядок float-а плавно переходит в мантиссу double-а... Браво!
Вы утрируете по моему. Мантиса должна перейти в мантису, показатель в показатель.. Если все корректно делать то не будет никакова шума , я так и не понимаю в чем сложность, но почему то этого нет.
Re[6]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, _FRED_, Вы писали:
V>>>В принципе при сравнении двух дробных чисел нельзя использовать явную проверку на равенство, нужно проверять V>>>является ли модуль разности менее какой-либо точности, определенной для данной задачи. _>>Про сравнение согласен, если в коде есть сравнение двух плавающих — тут явно чтото не так.
_FR>Оба утверждения неверны. Что "не так" в следующем сравнении:
Здравствуйте, barn_czn, Вы писали:
_>Здравствуйте, samius, Вы писали:
S>>Здравствуйте, Аноним, Вы писали:
А>>>Здравствуйте, barn_czn, Вы писали:
А>>>Все зависит от компилятора!!! При приведении типа часть компиляторов просто копирует кусок памяти меньшего размера (float) в больший (doudle). Все что было больше размера меньшего операнда остается. S>>И порядок float-а плавно переходит в мантиссу double-а... Браво!
_>Вы утрируете по моему. Мантиса должна перейти в мантису, показатель в показатель.. Если все корректно делать то не будет никакова шума , я так и не понимаю в чем сложность, но почему то этого нет.
Это не моя идея, а Аноним-а, см. выделенное.
Re[6]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, barn_czn, Вы писали:
V>>>В принципе при сравнении двух дробных чисел нельзя использовать явную проверку на равенство, нужно проверять V>>>является ли модуль разности менее какой-либо точности, определенной для данной задачи.
_>>Про сравнение согласен, если в коде есть сравнение двух плавающих — тут явно чтото не так.
_FR>Оба утверждения неверны. Что "не так" в следующем сравнении: _FR>
Здравствуйте, venicum, Вы писали:
V>>>>В принципе при сравнении двух дробных чисел нельзя использовать явную проверку на равенство, нужно проверять V>>>>является ли модуль разности менее какой-либо точности, определенной для данной задачи. _>>>Про сравнение согласен, если в коде есть сравнение двух плавающих — тут явно чтото не так. _FR>>Оба утверждения неверны. Что "не так" в следующем сравнении:
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, venicum, Вы писали:
V>>>>>В принципе при сравнении двух дробных чисел нельзя использовать явную проверку на равенство, нужно проверять V>>>>>является ли модуль разности менее какой-либо точности, определенной для данной задачи. _>>>>Про сравнение согласен, если в коде есть сравнение двух плавающих — тут явно чтото не так. _FR>>>Оба утверждения неверны. Что "не так" в следующем сравнении: _FR>
_FR>Ты бы хоть показал что изменил, убрав мои цитаты. _FR>Твой ответ не даёт ответ на мой вопрос: Ну и что же "не так" в моём сравнении?
Вы бы посмотрели на цифры, ввели бы код в VS200>=8.
Я не сказал, что ваш пример не верен, я также не говорил в своем посте, что сравнивать числа с плавающей точкой явно нельзя.
('В принципе' — вводная конструкция, выражает степень не уверенности. Извините, что не обособил с обеих сторон.)
Мой пример показывает, что такое сравнение не всегда корректно => целесообразно, например делать так: _FR>
Здравствуйте, barn_czn, Вы писали:
_>Собственно сабж. _>Народ, может мне ктонить ответить мочему так работает приведение. _>У меня есть предположение что шум появляется из-за того что размер float меньше размера double, и оставшаяся часть мантисы заполняется шумом. _>Вопрос — почему шумом а не нулями?
Не шумом, а именно нулями (двоичными). Теперь откуда берутся десятичные цифры в конце double:
Число 0.001 в формате Single записывается как
В этой записи первый бит — знак (+), следующие 8 битов — экспонента со смещением 127, остальные 23 бита — мантисса (без скрытого единичного бита)
Я разделил эти части точками и добавил скрытый бит мантиссы:
0.01110101.(1)00000110001001001101111
Значение экспоненты 0x75 = 117; Вычитаем смещение 117 — 127 = -10
Таким образом в формате Single имеем
Здравствуйте, venicum, Вы писали:
V>Я не сказал, что ваш пример не верен, я также не говорил в своем посте, что сравнивать числа с плавающей точкой явно нельзя.
Сказали, что
В принципе при сравнении двух дробных чисел нельзя использовать явную проверку на равенство, нужно проверять
является ли модуль разности менее какой-либо точности, определенной для данной задачи.
Отквоченное не верно. В моём примере числа можно сравнивать безо всякого "модуля разности".
V>Мой пример показывает, что такое сравнение не всегда корректно
Я этого и не оспаривал, но "не всегда корректно" как-то не следует из ваших слов (см. цитату выше).
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, barn_czn, Вы писали:
_>согласитесь, что приведение от float к double — это в некотором смысле повышение точности переменной, и от повышения точности не должно возникать каких то погрешностей. а они возникают, что очень странно.
_>а про представление в 2м виде — да мне все равно как оно там хранится, _>у меня равенство (decimal)0.001f == (decimal)(double)0.001f не выполняется _>(здесь приведение к decimal выполняет роль объективного сравнения), вот в чем жесть.
Никакой жести нет. Просто убери приведение к decimal и не морочь себе голову "объективными сравнениями", а почитай как устроены числа с плавающей запятой.
Здравствуйте, samius, Вы писали:
S>Жесть в том, что это пишет разработчик с минимум семилетним стажем (судя по профилю)
Ну не сталкивался он за 7 лет с необходимостью сравнивать числа с плавающей точкой. Только вот его опыт приводит к излишней самоуверенности.
Лично я сталкивался с этим только в 1-м реальном проекте (ну и плюс лабы по мат. моделированию). Правда опыт у меня в пару-тройку раз меньше.
Здравствуйте, barn_czn, Вы писали:
LVV>>Дык попробуй сам вручную перевести 0.001 из десятичной в двоичную. А потом обратно. И помедитируй над результатами.
_>Не понимаю.
_>0.001 = 1 * 10^-3, т.е.
_>Мантиса = 000...0001 _>Степень = +1 (знак "-") 000..100
_>Ну как так, кол-во нулей не важно. _>Где здесь бесконечная периодическая двоичная запись?
Срочно в инверситет, получать профильное образование!