math problems

Just starting out? Need help? Post your questions and find answers here.
ludoke
Enthusiast
Enthusiast
Posts: 153
Joined: Fri Jul 08, 2016 5:35 pm
Location: Essen (Belgium)

math problems

Post by ludoke »

Is there a good solution in pb for avoiding conversion errors from string to double ???

Code: Select all

;testprogram snippet
;purpose milling a circle with depth increment

T_total$="2.00"     ;result inputgadget T_total depth
T_increment$="0.20" ;result inputgadget increment depth/pass
increment.d=ValD(T_increment$)  ;convert to double
total.d=ValD(T_total$)
new_total.d=0
;Debug increment    ;Small conversion error,I suppose this is normal
;Debug total 

Repeat  
   new_total=new_total+increment
   Debug new_total          
 Until new_total>= total
 ;problem :The loop is run ONCE too much 
 ;So you have To take this into account !!!
 ;I try the same in BASCOM (basic for microcontroller) and this works well ,I don't know in other programming languages?

;I can work around this problem 
;total=Int(total*1000)
;increment=Int(increment*1000) ;this works,is there a better solution in purebasic ??
;Debug total
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: math problems

Post by wilbert »

You could calculate the number of steps.

Code: Select all

T_total$="2.00"     ;result inputgadget T_total depth
T_increment$="0.20" ;result inputgadget increment depth/pass
increment.d=ValD(T_increment$)  ;convert to double
total.d=ValD(T_total$)

nSteps.i = total / increment  ; number of steps
cStep.i = 0                   ; current step                 
While cStep < nSteps
  cStep + 1
  Debug total * cStep / nSteps
Wend
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
kenmo
Addict
Addict
Posts: 1967
Joined: Tue Dec 23, 2003 3:54 am

Re: math problems

Post by kenmo »

Problem has nothing to do with the string conversion part, it's the classic "floats can't store most numbers exactly" problem.

Same results in C:

Code: Select all

void main(void) {
  printf("%.17f \r\n\r\n", 0.20); // Can't store 1/5 exactly
  
  double increment = 0.20;
  double total = 2.00;
  double new_total = 0;
  do {
    new_total += increment;
    printf("%.17f \r\n", new_total);
  } while (new_total < total);
}
Output:

Code: Select all

0.20000000000000001

0.20000000000000001
0.40000000000000002
0.60000000000000009
0.80000000000000004
1.00000000000000000
1.20000000000000000
1.39999999999999990
1.59999999999999990
1.79999999999999980
1.99999999999999980
2.19999999999999970
Yes, the better methods are, use "fixed point" integers like you said, or divide the interval like Wilbert said.
Marc56us
Addict
Addict
Posts: 1477
Joined: Sat Feb 08, 2014 3:26 pm

Re: math problems

Post by Marc56us »

Use Break

Code: Select all

T_total$       = "2.00"     ;result inputgadget T_total depth
T_increment$   = "0.20"     ;result inputgadget increment depth/pass
increment.d    = ValD(T_increment$)  ;convert to double
total.d        = ValD(T_total$)
new_total.d    = 0

Repeat 
     new_total = new_total + increment
     If new_total >= total
          Break
     EndIf
     Debug "" + new_total 
Until new_total >= total
:idea:

Code: Select all

Debug "" + new_total  
:arrow:

Code: Select all

0.2
0.4
0.6
0.8
1
1.2
1.4
1.6
1.8
2
Or with new function: FormatNumber() (PB > 5.50)

Code: Select all

Debug FormatNumber(new_total, 2)
:arrow:

Code: Select all

0.20
0.40
0.60
0.80
1.00
1.20
1.40
1.60
1.80
2.00
:wink:
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: math problems

Post by wilbert »

Marc56us wrote:Use Break
Break still has it's problems.
Try your code with "1.00" or "3.00" for T_total$ and the last step is missing.
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply