Автор Тема: Фокус с числами в Blender или своеобразный Python  (Прочитано 2179 раз)

Оффлайн JBlender

  • Житель
Привет!
Сегодня заинтересовался разработкой аддонов под Blender и тут столкнулся с нововведением. :)
Захожу в консоль Python и ввожу:

>>> 0.1 + 0.1 + 0.1
0.30000000000000004

Я испугался. Запустил калькулятор перепроверил - 0.3. :)

>>> 0.1 + 0.1 + 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1
0.9999999999999999

Я еще больше испугался. Подумал законы математики поменялись, а я прошел мимо. :)
Запустил Visual Studio проверил в нем - 1.

Я конечно слышал про теорию 2+2=5... но думал, что это только теория. :)
Я убежден, что разработчики Blender, Python далеко не самые глупые люди.
Посему мои вопросы очевидны.

1. Почему так?
2. Кто виноват Blender\Python?

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #1 : 16 Февраль 2017, 14:32:00 »
Гы-гы, таки всё хорошо. Обычные ошибки округления чисел с плавающей точкой. Связано с тем, что комп работает в двоичной системе, а мы пользуемся десятичной, при переводе из системы в систему Питон выдаёт то, что получается. Читайте документацию по Питону, там это расписано. Блендер, естественно, тут вообще ни при чём.

В Питоновской библиотеке есть специальный модуль Decimal, работающий с точными числами. Рекомендуется для бухгалтерских/финансовых расчетов. А для Блендера и обычной точности хватит.


Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #2 : 16 Февраль 2017, 15:01:49 »
Чтобы продемонстрировать, что не только Питон "такой неточный", вот проверка на C:

Код
#include <stdio.h>

int main() {
double a=0.1+0.1+0.1;
printf("%20.19f", a);
};
Выдало
Код
0.3000000000000000444

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #3 : 16 Февраль 2017, 15:49:45 »
"Остапа понесло..."

Вот тоже самое в языке Sheme (диалект Лиспа):

Код
> (+ 0.1 0.1)
0.2
> (+ 0.1 0.1 0.1)
0.30000000000000004

Оффлайн JBlender

  • Житель
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #4 : 16 Февраль 2017, 15:56:24 »
Чтобы продемонстрировать, что не только Питон "такой неточный", вот проверка на C:

Код
#include <stdio.h>

int main() {
double a=0.1+0.1+0.1;
printf("%20.19f", a);
};
Выдало
Код
0.3000000000000000444
Ааааа.... Понятно т.е. это "баг" питона.
Насколько я понял в C, тоже все нормально если не вызывать принудительно. Я про "%20.19f".

Т.е. получается все остальные языки по умолчанию округляют float до нужного порядка и только питон отличается умом и сообразительностью?

Оффлайн JBlender

  • Житель
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #5 : 16 Февраль 2017, 16:01:17 »
"Остапа понесло..."
Вот тоже самое в языке Sheme (диалект Лиспа):
Со Sheme не работа, но вот С, С++, C#, Pascal, PHP... и много др. языков по умолчанию вроде такого не встречал. Я правда и работа редко float и максимум с сотыми.
Сегодня проверил на VB там тоже вcе хорошо.
« Последнее редактирование: 16 Февраль 2017, 16:16:38 от JBlender »

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #6 : 16 Февраль 2017, 16:15:28 »
Цитировать
Насколько я понял в C, тоже все нормально если не вызывать принудительно. Я про "%20.19f".
Что значит "вызывать принудительно"? Если написать
Код
printf("%f", a);
то ответ выглядит 0.30000 . Это не значит, что точность выше, просто не все цифры по умолчанию в printf попадают. А "%20.19f" выводит всё, что есть в переменной на самом деле.

Вот ещё с D поиграл:
Если тупо
Код
import std.stdio;
void main() {
float a=0.1+0.1+0.1;
writeln(a);
}
то ответ красивый: 0.3

А если увеличивать выводимую точность, то всё меняется:
Код
import std.format;
import std.stdio;
void main() {
float a=0.1+0.1+0.1;
writeln(format("%20.19f", a));

double b=0.1+0.1+0.1;
writeln(format("%20.19f", b));
}
Для float выдало 0.3000000119209289551
Для double выдало 0.2999999999999999889

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #7 : 16 Февраль 2017, 16:39:02 »
Цитировать
Я конечно слышал про теорию 2+2=5
http://3.bp.blogspot.com/-1RWhjvKWnL0/T_iqq_Vkv1I/AAAAAAAAAns/Yc_nFd02tlU/s1600/97961.jpeg
 ;D

Оффлайн JBlender

  • Житель
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #8 : 16 Февраль 2017, 16:39:35 »
Что значит "вызывать принудительно"? Если написать
Код
printf("%f", a);
то ответ выглядит 0.30000 . Это не значит, что точность выше, просто не все цифры по умолчанию в printf попадают. А "%20.19f" выводит всё, что есть в переменной на самом деле.
:) Вы наверное, не много ошиблись говоря про точность
0.1+0.1+0.1 = 0.30000000000000000, а не 0.30000000000000004 - по математическим законам.
А то, что машина считает не верно, это вопрос второй.

Я про это и говорю, просто мне видать попадались языки которые как раз выводили "не все цифры" по умолчанию, а много цифр после запятой запрашивать не было необходимости.

Теперь я понял проблему Cycles Developers по части Equal Math Node - https://www.google.ru/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=0ahUKEwijiPuW3ZTSAhWCEiwKHVsNDwAQFgghMAE&url=https%3A%2F%2Fdeveloper.blender.org%2FD1197&usg=AFQjCNGwXBxp0OkRXJ3GRHmA8jpg_r0YLQ&sig2=XjcdvN4H6Pjo-kQT_S2a8Q&bvm=bv.147134024,d.bGg

Большое спасибо, что прояснили вопрос.

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #9 : 16 Февраль 2017, 16:49:32 »
Цитировать
Теперь я понял проблему Cycles Developers по части Equal Math Node
Ну как бы известный факт, что числа с плавающей точкой нельзя просто на равенство сравнивать. Нужно объявлять epsilon, вычитать, и сравнивать разницу с этим epsilon.

Оффлайн JBlender

  • Житель
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #10 : 16 Февраль 2017, 16:51:03 »
Цитировать
Я конечно слышал про теорию 2+2=5
http://3.bp.blogspot.com/-1RWhjvKWnL0/T_iqq_Vkv1I/AAAAAAAAAns/Yc_nFd02tlU/s1600/97961.jpeg
 ;D
Мне кажется подвох в середине. :) А так прикольно. :)

Оффлайн JBlender

  • Житель
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #11 : 16 Февраль 2017, 17:06:53 »
Цитировать
Теперь я понял проблему Cycles Developers по части Equal Math Node
Ну как бы известный факт, что числа с плавающей точкой нельзя просто на равенство сравнивать. Нужно объявлять epsilon, вычитать, и сравнивать разницу с этим epsilon.
Похоже не настолько известный. Скорее странный.
Почему этот баг до сих пор не поправили? Ну и перевели бы все расчеты на Decimal и пр. библиотеки...

Оффлайн Samovar

  • Житель
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #12 : 16 Февраль 2017, 19:13:18 »
...а округление почему бы не использовать?

Код
>>> round ( 0.1 + 0.1 + 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1 ,5)
1.0


...а так будет занятный результат :)
Код
>>> int (( 0.1 + 0.1 + 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1)*10)/10
0.9

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #13 : 16 Февраль 2017, 19:34:13 »
Цитировать
а так будет занятный результат
Вообще-то, я надеюсь, всем известно, что округлять с помощью int(x) нельзя, для этого как раз round существует.

Во 2-м Питоне результат ещё веселее:
Код
>>> int (( 0.1 + 0.1 + 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1)*10)/10
0

Оффлайн Samovar

  • Житель
Re: Фокус с числами в Blender или своеобразный Python
« Ответ #14 : 16 Февраль 2017, 19:34:47 »

Цитировать
Во 2-м Питоне результат ещё веселее
Прикольно :)

Я так понял, это проблема представления чисел с плавающей запятой, вообще.  Если есть возможность, то лучше хранить числа в формате с фиксированной запятой, но это будет нехило кушать память...
https://habrahabr.ru/post/112953/

 


Яметрика

* По форуму

* Рекламный блок

* Последние вложения

1 (1).png
Скачано: 68
Автор: LEXA ANЭGROWND
blender.png
Скачано: 78
Автор: ipv2007
4.png
Скачано: 102
Автор: hiroyukiss
2.png
Скачано: 122
Автор: hiroyukiss

Скачано: 113
Автор: Dilifa12