PDA

Просмотр полной версии : Десятичный дроби


Parker
04.04.2006, 09:16
Столкнулся с такой проблемой:


var i=0;
this.onEnterFrame=function():Void{
i+=0.1;
trace(i);
}


Все просто до нельзя. В аутпуте сначала все нормально показывает:

0.1
0.2
0.3
0.4
0.5

НО, дальше начинаются "ошибки":

5.8
5.9
5.99999999999999
6.09999999999999
6.19999999999999

Я слышал, что AS работает капризно с дробными числами, но что он творит подобные ошибки в таких примитивных операциях, честно для меня это была новость.

Собственно вопроса то никакого и нет, просто хотелось узнать Ваше мнение по данной проблеме.

Takato
04.04.2006, 10:10
Всё, сношу флэш нафиг


А вобще - дежавю - это сбой в Матрице

Takato
04.04.2006, 10:24
В результате срочно созваннного заседания, посвященного этой проблеме, решено было устроить опрос среди населения. На вопрос - "Как вы относитесь к подобному багу во флэше?", наша специальная комисия получила следующие ответы -

13,4 процента - "Первый раз слышу"
7,4 процента - "Не знаю..."
6,3 процента - "Такая тема уже обсуждалась на Флэшере
15,8 процентов - "Не надо использовать дроби во флэше"
16,6 процента - "Надо использовать код типа i+=1 j=i/10 trace(j);"
12,0 процента - "Надо деинсталирвать флэш"
47,5 процента - "Путин"
23,1 процента - "Не надо обращать внимания на мелочи"
5.99999999999999 процента - "Мне всё равно"


В опросе приняло участие 1024 человека из 1063 регионов страны, разных возрастных групп и телосложения

Samodelkin
04.04.2006, 11:31
Со Флэшем все нормально, это нас в школе неправильно учили...

DimZ
04.04.2006, 13:36
а может это их в школе не правильно учили?

Friday13
04.04.2006, 13:47
Одно из решений:
var i=0;
this.onEnterFrame=function():Void{
i+=0.1;
i=Number(String(i))
trace(i);
}

666
05.04.2006, 03:20
Одно из решений:
var i=0;
this.onEnterFrame=function():Void{
i+=0.1;
i=Number(String(i))
trace(i);
}
какой ужас :)

mr.N
05.04.2006, 05:35
Проблема действительно существует, я много раз с ней сталкивался. Решение одно - округлять. На каждом этапе вычисления.

haetorigam#
05.04.2006, 05:46
Проблема действительно существует, я много раз с ней сталкивался. Решение одно - округлять. На каждом этапе вычисления.
О, вот ещё
var i=90;
var m=Math.cos(i*Math.PI/180);
trace(m);

m=6.12303176911189e-17;
даже весело

Parker
05.04.2006, 09:02
Смотрю народу понравилось предлагать решения проблемы (хотя я и не просил) :) Скажу честно некоторые варианты решения меня ужаснули. Что ж кому не лень предлагайте еще более извращенные варианты - с удовольствием на них посмотрю. В конце концов - это же раздел ФЛЕЙМ - можно ж то хоть здесь оторваться :D

Takato
05.04.2006, 10:08
a=[0.1, 0.2, 0.3, 0.4, 0.5, 0.6...]

this.onEnterFrame=function():Void{
i+=1;
j=a[i]
trace(j);
}

motor4ik
05.04.2006, 10:41
this.onEnterFrame=function():Void{
i+=0.1;
j=i+0.00000000000001;
trace(j);
}

scourge ' kangaroo
05.04.2006, 11:16
извращённые варианты предлагать?... нучтож, flash это готично :taunt:

var i=0;
this.onEnterFrame=function():Void{
i+=0.1;

if (i < 0.1) j = 0
if (i < 0.2) j = 0.1
if (i < 0.3) j = 0.2
if (i < 0.4) j = 0.3
if (i < *) j = * // до бесконечности можно ((:

trace(j);
}

__i
05.04.2006, 11:56
берем ПХП и пишем

$k=0.000000000000001;
for ($i=0;$i<20;$i++){
$k+=0.01;
echo '<br>'.$k;
}

получаем

0.010000000000001
0.020000000000001
0.030000000000001
0.040000000000001
0.050000000000001
0.060000000000001
0.070000000000001
0.080000000000001
0.090000000000001
0.1
0.11
0.12
0.13
0.14
0.15
0.16
0.17
0.18
0.19
0.2


О боже! кто украл мою 0.000000000000001 в последних 10 значениях, Куда она девалась?!!!, это наверное ребята которые писали ПХП наплужили, что теперь с этим делать ужас!!!, мне страшно, как жить дальше?!!! и не работать......... %)))

Ну после всего этого мальчики/девочки идем учить мат. часть%). Читаем компьтерную литературу - лучше про ассемблер и представление вещественных чисем в компьютере, потом думаем потом опять читаем, опять думаем.... и так до тех пор пока не поймем куже таки девалась эта 0.00000000000001.

Parker
05.04.2006, 13:52
2__i
Ну умный малый, куды бечь, компьютерную литературу читал, пхп знает, диагноз - гений

Takato
05.04.2006, 20:37
и так до тех пор пока не поймем куже таки девалась эта 0.00000000000001

Вобщето это всем понятно, тем более такая тема на Флэшере уже была

K.A.T.A.F.A.L.K.E.R
05.04.2006, 21:36
А давайте конкурс: "предложи свой способ хранения дробей в памяти" :confused:

Takato
05.04.2006, 22:32
А давайте конкурс: "предложи свой способ хранения дробей в памяти"

А че там предлагать. Кто ваще придумал, что бит - это минимальная еденица информации? Про атом тоже раньше так орали - а оказалось, что он состоит из гораздо более мелких протонов и нейтронов, а те в свою очередь - из кварков. Вот и с битом тоже самое - надо найти (ввести) более мелкие еденицы измерения информации, и тогда в них запросто можно будет хранить дроби

artcraft
06.04.2006, 01:49
var i=0;
this.onEnterFrame=function():Void{
i++;
trace(i/10);
}
даже код длиннее не стал :~)

tiHo
06.04.2006, 19:06
нука.... а если так:


i=0
onEnterFrame=function(){
i+=0.1
trace(Math.cell(i))
}


Да, кстати:

не прикидывайтесь умными! непишите вы Void. и ; можно неставить в конце оператора.
хм.. а может вы умные?:) не, у умных таких ошибок не возникает:) невобиду, но ето так.

motor4ik
06.04.2006, 19:12
и че? не в обиду пишется раздельно, ты бы сначала русский выучил, прежде чем рассказывать программистам что писать, а что не писать!

artcraft
06.04.2006, 19:37
нука.... а если так:
i=0
onEnterFrame=function(){
i+=0.1
trace(Math.cell(i))
}
**Error** Scene=Scene 1, layer=Layer 1, frame=1:Line 4: There is no method with the name 'cell'.
trace(Math.cell(i))

Total ActionScript Errors: 1 Reported Errors: 1

:~)
Исправляем на Math.ceil и видим в оутпуте:

1
1
1
1
1
1
1
1
1
1
2
2
2
2
...

:~)

artcraft
06.04.2006, 19:47
не прикидывайтесь умными! непишите вы Void. и ; можно неставить в конце оператора.
оно можно, пока в коде 5 строк.
Но когда код становится посложнее, то привычка писать код правильно и указывать типы совсем не мешает :~)

__i
07.04.2006, 13:07
2__i
Ну умный малый, куды бечь, компьютерную литературу читал, пхп знает, диагноз - гений
Представь себе - ДА!, к тому же я еще умею пользоваться поиском и читать, что умные люди пишут, а не задавать глупых вопросов.

Parker
07.04.2006, 15:26
Представь себе - ДА!, к тому же я еще умею пользоваться поиском и читать, что умные люди пишут, а не задавать глупых вопросов.
а главное скромный - хехе

Niketas
08.04.2006, 00:23
О, вот ещё
var i=90;
var m=Math.cos(i*Math.PI/180);
trace(m);

m=6.12303176911189e-17;
даже весело
Не понимаю, зачем тебе вводить i=90, когда строка
var m=Math.cos(Math.PI/2);
и без того выдает m=6.12303176911189e-17;

Проблема в том, что PI во флэше, естественно, не идеальное. Напиши:
trace(Math.PI);
В Output'е появится следующее:
3.14159265358979
Всего лишь 14 знаков после запятой. Достаточно? Нет. Потому что при этом пи флэш выдает то m, которое ты написал.
Насколько я понимаю запись "е-17", это означает, что число умножено на 10 в минус семнадцатой степени. 6*10^-17 — почти ноль. Но не ноль.
Вот 100 знаков после запятой:
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
Этого, казалось, было бы достаточно. Нет. Флэшу все равно. Выражение Math.cos(*пи с сотней знаков*/2) дает то же самое.
Может, в проге недостаточно знаков? :) Наверное, знаков там хватает (видимо, и пи у них выводится неполностью).
Просто надо использовать Math.round() :)
Кстати, если нужно 1 452 717 знаков после запятой - вам нужно скачать архив (http://bio.fizteh.ru/student/spravochnik/pi/pi.zip) (673 Кб).

artcraft
08.04.2006, 01:00
Кстати, если нужно 1 452 717 знаков после запятой - вам нужно скачать архив (http://bio.fizteh.ru/student/spravochnik/pi/pi.zip) (673 Кб).
тем кому и этого мало - этой прогой можно посчитать пи длинной, например, в 10 мегабайт :~)