debug output of very small or very large numbers

Just starting out? Need help? Post your questions and find answers here.
Little John
Addict
Addict
Posts: 4780
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: debug output of very small or very large numbers

Post by Little John »

luis wrote:I explain it in a easily understandable way, concentrate :
It doesn't make much sense to me to discuss with you when you write with such a strange and arrogant attitude. It seems that you had a hard day or something.
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: debug output of very small or very large numbers

Post by freak »

> No, IMHO that's not another story. StrD(a) should give the correct result (if possible). Not doing so is a bug.

Floating point numbers are inherently imprecise and rounding errors accumulate with every calculation. Therefore, only the programmer can know up to which precision the number can be "trusted" (how many digits should be printed). There is no "correct result" when it comes to the precision of a floating point number. That is why the default precision is low enough that such things are not an issue. If you want to go higher you have to explicitly request it with the precision parameter.

Which of the following is "correct" in your opinion?

Code: Select all

Debug StrD(0.3)
Debug StrD(0.3, 34)
quidquid Latine dictum sit altum videtur
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: debug output of very small or very large numbers

Post by luis »

freak wrote: Which of the following is "correct" in your opinion?
The internal representation is the same, so that's not an issue when doing calculations using variables.
When I want to get a string representation I would like to get the one containing the max of information present in the binary equivalent, so the second one without the trailing zeros, if I don't need all that decimals I would specify a smaller param.

Code: Select all

Debug StrD(1/7)
Debug StrD(1/7, 17) ; same here
Wouldn't be possible ?
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
idle
Always Here
Always Here
Posts: 5848
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: debug output of very small or very large numbers

Post by idle »

klaus if you want scientific notation output

Code: Select all


ImportC "" 
   sprintf(*out,format.p-Ascii,val.d)
EndImport 

Procedure.s strE(v.d) 
   Protected sout.s,*output  
   *output = AllocateMemory(64)
   sprintf(*output,"%g",v) 
   sout = PeekS(*output,-1,#PB_Ascii) 
   FreeMemory(*output)
   ProcedureReturn sout 
 EndProcedure   
  
a.d = 1e-34
b.f = 1e-15

Debug stre(a) 
Debug stre(b) 
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: debug output of very small or very large numbers

Post by luis »

@idle

shouldn't be this way ?

Code: Select all

ImportC ""
   sprintf(*out,format.p-Ascii,val.d)
EndImport
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
idle
Always Here
Always Here
Posts: 5848
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: debug output of very small or very large numbers

Post by idle »

thanks I didn't test it on 32bit updated it
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
skywalk
Addict
Addict
Posts: 4212
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: debug output of very small or very large numbers

Post by skywalk »

The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: debug output of very small or very large numbers

Post by wilbert »

@Idle, a little faster

Code: Select all

ImportC "" 
  sprintf(*out, format.p-ascii, val.d)
  strtod.d(n.p-ascii, *endptr)
EndImport 

Procedure.s StrE(v.d) 
  Protected s.s{16}
  sprintf(@s, "%g", v)
  CompilerIf #PB_Compiler_Unicode
    ProcedureReturn PeekS(@s, -1, #PB_Ascii) 
  CompilerElse
    ProcedureReturn s
  CompilerEndIf
EndProcedure

Procedure.d ValE(s.s)
  Protected e.i
  ProcedureReturn strtod(s, @e)
EndProcedure
I also added ValE()
Debug ValE("1.5E2")
Last edited by wilbert on Thu Aug 22, 2013 8:03 am, edited 3 times in total.
Windows (x64)
Raspberry Pi OS (Arm64)
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: debug output of very small or very large numbers

Post by davido »

Could try something like this:

Code: Select all

a.d = 9.23456e-123
Macro Rubbish()
  InsertString(Trim(Mid(StrD(a,Len(RTrim(Mid(StrD(a,Int(Abs(Log10(a))) + 6),3),"0"))),3),"0"),".",2) + "e-" +
      Str(Len(RTrim(Mid(StrD(a,Int(Abs(Log10(a))) + 6),3),"0")) - Len(Trim(Mid(StrD(a,Int(Abs(Log10(a))) + 6),3),"0"))+1)
EndMacro

Debug Rubbish()

DE AA EB
Lothar Schirm
User
User
Posts: 54
Joined: Mon Nov 26, 2012 4:57 pm

Re: debug output of very small or very large numbers

Post by Lothar Schirm »

I use the following procedure for numbers in a scientific format:

Code: Select all

Procedure.s Format(a.d, dez.i)
  ; Liefert eine Zahl a im wissenschaftlichen Zahlenformat zurück, 
  ; dez = Anzahl der Dezimalstellen der Mantisse.
  ; Beispiel: Format(-9235.7278, 3) liefert -9.236e3
  
  Protected.i i, Exponent
  Protected.d x, Mantisse
  Protected.s s
  
  If a = 0
    s = Space(1) + StrD(0, dez) + "e" + Str(0)
  Else
    x = Log10(Abs(a))
    Exponent = Int(x)
    Mantisse = Pow(10, x - Exponent)
    ; Null vor dem Dezimalpunkt vermeiden:
    If Mantisse < 1
      Mantisse = 10 * Mantisse
      Exponent = Exponent - 1
    EndIf
    If a > 0
      s = Space(1) + StrD(Mantisse, dez) + "e" + Str(Exponent)
    Else
      s = "-" + StrD(Mantisse, dez) + "e" + Str(Exponent)
    EndIf
  EndIf
  
  ProcedureReturn s
  
EndProcedure

debug Format(-9235.7278, 3)
:D
Little John
Addict
Addict
Posts: 4780
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: debug output of very small or very large numbers

Post by Little John »

freak wrote:> No, IMHO that's not another story. StrD(a) should give the correct result (if possible). Not doing so is a bug.

Floating point numbers are inherently imprecise and rounding errors accumulate with every calculation. Therefore, only the programmer can know up to which precision the number can be "trusted" (how many digits should be printed). There is no "correct result" when it comes to the precision of a floating point number.
You are right with this of course.
freak wrote:That is why the default precision is low enough that such things are not an issue.
Hmm? When

Code: Select all

a.d = 1e-34
Debug StrD(a)
outputs 0 rather than 0.0000000000000000000000000000000001, that is the issue which has been mentioned before, no?
freak wrote:If you want to go higher you have to explicitly request it with the precision parameter.
It should be the other way round IMHO: StrD(a) should output the maximum number of digits (without leading zeros before and trailing zeros after the decimal point), and we'd have to request explicitly when we want rounded values with less decimal digits.
freak wrote:Which of the following is "correct" in your opinion?

Code: Select all

Debug StrD(0.3)
Debug StrD(0.3, 34)
You are right that floating point computation is by nature inexact.
What I want to say is that as few as possible digits should get lost by default, when the result of a floating point calculation is converted to a string by StrD() or StrF().

Code: Select all

; -- Example 1
Debug StrD(1e-34)
; => 0
Debug StrD(1e-34, 34)
; => 0.0000000000000000000000000000000001

; -- Example 2
Debug StrD(0.3)
; => 0.3
Debug StrD(0.3, 34)
; => 0.3000000000000000400000000000000000
In the first example, the first output is not so good. In the second example, the second output is not so good. The difference between both not-so-good outputs is:
When I read "0.3000000000000000400000000000000000" (according to my suggestion it would be "0.30000000000000004") in the second example, I see immediately that the value is ""0.3" when rounded to 1 decimal digit. But when I read "0" in the first example, I cannot see that the value should be "0.0000000000000000000000000000000001".
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: debug output of very small or very large numbers

Post by freak »

luis wrote:When I want to get a string representation I would like to get the one containing the max of information present in the binary equivalent, so the second one without the trailing zeros, if I don't need all that decimals I would specify a smaller param.
Are you serious? So when you present numbers to your program's users, you are not worried about tons of bugreports in the form of "I put 0.3 in the field, but it returns 0.29999999 the next time. Your program is broken". Good luck explaining the IEEE floating point standard to each and every one of them. We even get programmers here every once in a while who have a hard time understanding that!

If you want to preset data to the end user, you cannot use such precisions. Imho, presenting data to a programmer (you) is the rather rare case in general, so it should not be the default behavior.

Little John wrote:Hmm? When

Code: Select all

a.d = 1e-34
Debug StrD(a)
outputs 0 rather than 0.0000000000000000000000000000000001, that is the issue which has been mentioned before, no?
Well, but you are not using maximum precision here either. You are rounding too. You can display more digits:

Code: Select all

a.d = 1e-34
Debug StrD(a, 51)
Is that what you want as output?


Besides, as I said above, StrD() has no way of knowing if 0.0000000000000000000000000000000001 is the actual result you want to display or whether you actually want to display 0 and the rest is just accumulated error from calculations. To illustrate that point, try the following:

Code: Select all

a.d = 0
For i = 1 To 10: a + 0.3: Next i ; add some values
For i = 1 To 5: a - 0.6: Next i  ; subtract the same amount. Result should be 0
Debug StrD(a, 51)
So is -0.00000000000000066613381477509392 really the output you want to see in this case? That is why i said: Only the programmer knows how many digits can be considered valid. StrD() cannot decide.


Anyway, this is no bug. The command works as designed. You are free to have your own opinion though, that is why the command has an optional parameter for the digits after all ;)
quidquid Latine dictum sit altum videtur
Little John
Addict
Addict
Posts: 4780
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: debug output of very small or very large numbers

Post by Little John »

freak wrote:

Code: Select all

a.d = 1e-34
Debug StrD(a, 51)
Is that what you want as output?
... without trailing zeros.
freak wrote:That is why i said: Only the programmer knows how many digits can be considered valid. StrD() cannot decide.
I absolutely agree. But the programmer's decision has to be based on something ... on as much information as possible. And because of this, I explained in the last paragraph of my previous post, why one way of handling things is IMHO better than the other.
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: debug output of very small or very large numbers

Post by freak »

Little John wrote:
freak wrote:

Code: Select all

a.d = 1e-34
Debug StrD(a, 51)
Is that what you want as output?
... without trailing zeros.
The output is: 0.000000000000000000000000000000000099999999999999993
quidquid Latine dictum sit altum videtur
Klaus_1963
User
User
Posts: 29
Joined: Wed Nov 25, 2009 9:37 am

Re: debug output of very small or very large numbers

Post by Klaus_1963 »

Thanks to all for the great discussion.

Floating point variables consists of two parts: mantissa and exponent. Mantissa can be very accurate although the exponent is very low or high. Means the display of very small or huge numbers makes definitely sense. Otherwise you couldn't use computers for scientific applications. The scientist is responsible to check, if the accuracy of the result fits with the needs of his examination. I think: an IT-specialist should not limit the work of a scientist. Every scientist uses programming languages only as one of a lot of tools to do his job. A programming language has to be simple to use and reliable. Focus of a scientist is set to solve the scientific problem, not to solve programming problems caused by the language. In addition to this as a PB-User I don't like to bypass a problem which is not one in other languages: so I will use other languages as first languages in the future as I've done it in the past. Nevertheless I think PB will comply the features I need in the near future. There is no doubt that PB has a great potential for scientific applications too.

Have a good weekend

Klaus
PureBasic 4.72 LTS - Windows / MacOS / Linux / strong coffee / stronger coffee / Coffee intravenously...
Post Reply