Вверх ↑
Этот топик читают: Гость
Ответов: 91
Рейтинг: 0
#1: 2020-08-03 11:13:05 ЛС | профиль | цитата
Здравствуйте!
Не пойму, почему в простой операции вычитания появляется погрешность?

в точках отладки видно 40159.96-40158.0=1.95999999999913


Add(MainForm,15551238,105,189)
{
Width=529
Height=449
Caption="Домашний из Exel в AdsMan"
link(onActivate,11230900:doEvent1,[(153,195)(153,342)])
}
Add(Edit,6514230,231,287)
{
Left=95
Top=35
Width=135
Text="11:09:19:20"
link(onChange,9832680:doCompare,[])
link(Str,14626914:Value,[])
}
Add(MultiStrPart,5645447,378,294)
{
Char=":"
Count=4
link(onSplit,16227320:doCalc,[(422,300)(422,337)(364,337)(364,356)])
}
Add(MathParse,16227320,378,350)
{
DataCount=4
MathStr="%1*3600 + %2*60 + %3 + %4*0.04"
link(X1,5645447:Part1,[])
link(X2,5645447:Part2,[])
link(X3,5645447:Part3,[])
link(X4,5645447:Part4,[])
}
Add(Memory,14626914,231,196)
{
Default=String(11:09:18:00)
}
Add(DateConvertor,9690866,868,322)
{
Mode=16
Format="HH:mm:ss"
Point(Result)
}
Add(Hub,4953039,609,350)
{
OutCount=8
link(onEvent1,13190396:doStrCat,[(745,356)(745,328)])
link(onEvent4,6336814:doSplit,[])
link(onEvent5,13178911:doSplit,[(636,384)(636,447)])
}
Add(Edit,5655643,1092,371)
{
Left=90
Top=125
Width=140
Text=""
}
Add(Edit,1343489,1092,441)
{
Left=90
Top=150
Width=140
Text=""
}
Add(MathParse,15435686,882,371)
{
DataCount=1
MathStr="%1*100/4"
link(onResult,12515832:doWork2,[])
}
Add(StrPart,6336814,679,371)
{
Char="."
Point(onNotFound)
link(onSplit,8055310:doString,[])
link(onNotFound,10871200:doClear,[(723,391)(723,398)])
}
Add(FormatStr,8055310,826,371)
{
DataCount=1
Mask="0.%1"
link(onFString,15435686:doCalc,[])
}
Add(StrPart,13178911,742,441)
{
Char="."
Point(onNotFound)
link(onSplit,351203:doWork2,[])
link(onNotFound,8563622:doClear,[(786,461)(786,468)])
}
Add(FormatStr,11352897,861,441)
{
Mask="%2.%1"
Point(FString)
link(onFString,2892672:doLength,[])
link(Str2,13208133:Var2,[])
}
Add(FormatStr,1515380,1008,371)
{
Mask="%2:%1"
link(onFString,5655643:doText,[])
link(Str2,13208133:Var3,[(1021,362)])
}
Add(GetDataEx,13208133,868,357)
{
link(Data,9690866:Result,[])
}
Add(StrMask,9832680,301,287)
{
Mask="##:##:##:##"
link(onTrue,5645447:doSplit,[])
}
Add(Memory,8563622,798,455)
{
Default=String(00)
link(onData,351203:doWork3,[(844,461)])
}
Add(HubEx,351203,840,441)
{
link(onEvent,11352897:doString,[])
}
Add(Memory,10871200,735,385)
{
Default=String(00)
link(onData,12515832:doWork3,[(811,391)(811,428)(977,428)])
}
Add(HubEx,12515832,973,371)
{
link(onEvent,1515380:doString,[])
}
Add(Length,2892672,910,441)
{
link(onLength,4567632:doCompare,[])
}
Add(If_else,4567632,959,441)
{
Op2=Integer(11)
link(onTrue,5478475:doString,[])
link(onFalse,4900880:doString,[(1010,454)(1010,496)])
}
Add(FormatStr,4900880,1022,490)
{
Mask="%1%2"
link(onFString,10977111:doWork3,[(1061,496)])
link(Str1,16448502:Var3,[(1028,482)])
link(Str2,14942401:Value,[(1035,478)(1067,478)(1067,534)(1098,534)])
}
Add(HubEx,10977111,1057,441)
{
link(onEvent,1343489:doText,[])
}
Add(FormatStr,5478475,1022,441)
{
Mask="%1"
link(onFString,10977111:doWork2,[])
link(Str1,16448502:Var1,[(1028,429)(1014,429)])
}
Add(GetDataEx,16448502,1008,477)
{
Angle=3
link(Data,11352897:FString,[(867,482)])
}
Add(Memory,14942401,1092,490)
{
Default=String(0)
}
Add(StrCat,13190396,763,322)
{
link(onStrCat,9690866:doConvert,[])
}
Add(Edit,15697781,231,490)
{
Left=95
Top=60
Width=135
Text="11:09:19:20"
link(onChange,3595563:doCompare,[])
link(Str,11553315:Value,[])
}
Add(MultiStrPart,640633,378,497)
{
Char=":"
Count=4
link(onSplit,9457343:doCalc,[(422,503)(422,540)(364,540)(364,559)])
}
Add(MathParse,9457343,378,553)
{
DataCount=4
MathStr="%1*3600 + %2*60 + %3 + %4*0.04"
link(X1,640633:Part1,[])
link(X2,640633:Part2,[])
link(X3,640633:Part3,[])
link(X4,640633:Part4,[])
}
Add(Memory,11553315,231,399)
{
Default=String(11:09:19:24)
}
Add(StrMask,3595563,301,490)
{
Mask="##:##:##:##"
link(onTrue,640633:doSplit,[])
}
Add(Hub,11230900,168,336)
{
OutCount=8
link(onEvent1,6514230:doText,[(206,342)(206,293)])
link(onEvent2,15697781:doText,[(206,349)(206,496)])
link(onEvent3,15704663:doOperation,[(315,356)(315,440)])
}
Add(Math,15704663,448,434)
{
OpType=1
AngleMode=1
link(onResult,12808265:doText,[(502,440)(502,356)])
link(Op1,1255876:Var,[(454,422)])
link(Op2,5239000:Var,[(461,408)])
}
Add(Edit,12808265,525,350)
{
Left=90
Top=90
Width=175
Text=""
link(onChange,4953039:doEvent1,[])
link(Str,353556:Var,[(531,338)])
}
Add(Debug,5239000,448,399)
{
link(Data,16227320:Result,[(384,408)])
}
Add(Debug,1255876,427,413)
{
link(Data,9457343:Result,[(419,422)(419,597)(384,597)])
}
Add(Debug,353556,504,336)
{
link(Data,15704663:Result,[(493,338)(493,478)(454,478)])
}


карма: 0

0
Ответов: 8892
Рейтинг: 823
#2: 2020-08-03 11:41:10 ЛС | профиль | цитата
wvlas, компьютер все математические (и все прочие) операции производит ИСКЛЮЧИТЕЛЬНО в двоичной системе и точное число в десятичной системе при переводе в двоичную превращается в приближённое и при обратном переводе результатов не может не быть погрешности в последних знаках.
карма: 19

0
Ответов: 91
Рейтинг: 0
#3: 2020-08-03 11:50:08 ЛС | профиль | цитата
windовый калькулятор тоже в двоичной системе вычисления производит, но результат 1,96

--- Добавлено в 2020-08-03 11:52:42


Add(MainForm,2953706,21,105)
{
link(onActivate,15704663:doOperation,[])
}
Add(Math,15704663,119,105)
{
OpType=1
AngleMode=1
link(onResult,12808265:doText,[])
link(Op1,160075:Value,[(125,47)(90,47)])
link(Op2,3466732:Value,[])
}
Add(Edit,12808265,217,105)
{
Left=90
Top=90
Width=175
Text=""
}
Add(Memory,160075,84,7)
{
Default=Real(40159.96)
}
Add(Memory,3466732,126,7)
{
Default=Real(40158)
}


От версии win не зависит? Вроде раньше коды писал такого не замечал.

--- Добавлено в 2020-08-03 12:13:32

Проверил на Xp тоже самое

Редактировалось 2 раз(а), последний 2020-08-03 12:13:32
карма: 0

0
Главный модератор
Ответов: 2997
Рейтинг: 395
#4: 2020-08-03 13:03:32 ЛС | профиль | цитата
В общем смысле можно почитать здесь. Если бы речь шла про .NET, то проблема решалась бы заменой используемого типа Double на тип Decimal . Об этом очень много написано в интернете. Теоретически в Delphi есть тип Currency с фиксированной точностью, но практически просто надо самостоятельно приводить результат операций с плавающей точкой к нужной точности.
карма: 6
Дорогу осилит идущий. Install/Update HiAsm.NET
0
Ответов: 207
Рейтинг: 14
#5: 2020-08-03 13:10:49 ЛС | профиль | цитата
wvlas, Уже ответил Nic
Нужно использовать тип Currency (финансовый), который предназначен для минимизации ошибок округления в бухгалтерских расчётах.

Add(MainForm,6320956,266,84)
{
Width=319
Height=65
Position=1
link(onCreate,2834044:dotest,[])
}
Add(InlineCode,2834044,322,98)
{
WorkPoints=#6:dotest|
EventPoints=#5:onRes|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|19: onRes:THI_Event;|50: procedure dotest(var _Data:TData; Index:word);|5: end;|0:|14:implementation|0:|28:procedure THiAsmUnit.dotest;|19:var x1,x2:Currency;|7:x:Real;|6:begin |13:x1:=40159.96;|10:x2:=40158;|11:x:=x1 - x2;|21:_hi_OnEvent(onRes,x);|4:end;|4:end.|
link(onRes,6320956:doCaption,[(362,104)(362,67)(254,67)(254,90)])
}

карма: 2

0
Ответов: 91
Рейтинг: 0
#6: 2020-08-03 14:39:13 ЛС | профиль | цитата
Каким способом это сделать в HIASM, применительно к вышеизложенной схеме? Каким элементом, или скрипт писать дополнительным элементом?
карма: 0

0
Главный модератор
Ответов: 2997
Рейтинг: 395
#7: 2020-08-03 15:19:56 ЛС | профиль | цитата
wvlas писал(а):
Каким способом это сделать в HIASM

Округление до нужного числа знаков после запятой

P.S.
Могли бы и сами поискать по форуму через Google запросом:
site:https://forum.hiasm.com округление

карма: 6
Дорогу осилит идущий. Install/Update HiAsm.NET
0
Ответов: 8892
Рейтинг: 823
#8: 2020-08-03 18:04:29 ЛС | профиль | цитата
wvlas, кое что сделано до нас В архиве схема, *.exe, и модуль *.pas для работы с большими числами, он должен сопровождать схему при компиляции.
https://forum.hiasm.com/getfile/39091

Редактировалось 1 раз(а), последний 2020-08-03 18:12:44
карма: 19

0
Ответов: 207
Рейтинг: 14
#9: 2020-08-03 20:59:19 ЛС | профиль | цитата
wvlas, Можно так. Добавил точки.
Add(MainForm,4603492,133,189)
{
link(onActivate,2834044:dotest,[])
}
Add(Edit,12808265,329,189)
{
Left=90
Top=90
Width=175
Text=""
}
Add(Memory,160075,196,91)
{
Default=Real(40159.96)
}
Add(Memory,3466732,238,91)
{
Default=Real(40158)
}
Add(InlineCode,2834044,231,189)
{
WorkPoints=#6:dotest|
EventPoints=#5:onRes|
DataPoints=#3:op1|3:op2|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|28: op1,op2,onRes:THI_Event; |50: procedure dotest(var _Data:TData; Index:word);|5: end;|0:|14:implementation|0:|28:procedure THiAsmUnit.dotest;|19:var x1,x2:Currency;|7:x:Real;|6:begin |24:x1:=ReadReal(_Data,op1);|24:x2:=ReadReal(_Data,op2);|14:x:= x1 - x2; |21:_hi_OnEvent(onRes,x);|4:end;|4:end.|
link(onRes,12808265:doText,[])
link(op1,160075:Value,[(237,180)(202,180)])
link(op2,3466732:Value,[])
}

Редактировалось 1 раз(а), последний 2020-08-03 21:02:56
карма: 2

0
Ответов: 91
Рейтинг: 0
#10: 2020-08-04 11:44:53 ЛС | профиль | цитата
Всем большое спасибо!!! Буду округлять.

Nic писал(а):
P.S.
Могли бы и сами поискать по форуму через Google запросом:
site:https://forum.hiasm.com округление

Задавал этот вопрос на предыдущее сообщение, имея ввиду "использовать тип Currency (финансовый)" как это сделать в HIASM, а не как округлять. А поиском искал, все про округление читал.
карма: 0

0
Ответов: 5227
Рейтинг: 587
#11: 2020-08-04 15:39:26 ЛС | профиль | цитата
VBS работает с датами, числами, строками. Не нужно изучать KOL и Delphi (школьники на васике писать могут)
Вообще задача решаема была в 2-3 минуты

Add(MainForm,7287395,119,182)
{
link(onActivate,12287855:doWork,[(184,188)(184,230)])
}
Add(Math,15704663,217,182)
{
OpType=1
AngleMode=1
link(onResult,8540420:doWork2,[])
link(Op1,14214765:Var2,[])
link(Op2,2047416:Var2,[])
}
Add(Edit,12808265,357,182)
{
Left=90
Top=90
Width=175
Text=""
}
Add(Memory,160075,182,84)
{
Default=Real(40159.96)
}
Add(Memory,3466732,224,84)
{
Default=Real(40158)
}
Add(VBJScript,12287855,273,224)
{
WorkPoints=#6:doWork|
EventPoints=#5:onRes|
DataPoints=#3:Op1|3:Op2|
Script=#18:Sub doWork(dt,idx)|41: sys.onRes CCur(sys.Op1) - CCur(sys.Op2)|7:End Sub|
link(Op1,14214765:Var3,[(279,152)])
link(Op2,2047416:Var3,[(286,166)])
link(onRes,8540420:doWork3,[(333,230)])
}
Add(GetDataEx,14214765,217,147)
{
link(Data,160075:Value,[(223,124)(188,124)])
}
Add(GetDataEx,2047416,224,161)
{
link(Data,3466732:Value,[])
}
Add(HubEx,8540420,329,182)
{
link(onEvent,12808265:doText,[])
}

карма: 4
Мой форум - http://hiasm.bbtalk.me/ схемы, компоненты...
0
Ответов: 2059
Рейтинг: 132
#12: 2020-08-04 16:27:51 ЛС | профиль | цитата
Лёнь, смотри как:
Херозо капитпна!
...
Вроде ссат однако! м я тоже!!!
... отбился, у меня с армии ещё 2 рожка изоленой перекручкны

Не сердись!
Сам не пойму!
Хочешь расскжу?

Устал, и раны надо эализывить!!!


Лёнь ты в Москве?

Редактировалось 5 раз(а), последний 2020-08-04 17:15:50
карма: 6

0
12
Сообщение
...
Прикрепленные файлы
(файлы не залиты)