Truncate the zeros in a real or floating point number

Started by etow, February 18, 2008, 03:03:21 PM

Previous topic - Next topic

etow

Hi

Is there a way to truncate or get rid of the remaining zeros in a floating point or real number after decimal point?

For example,  a real number :   1.552000000

Is there a way to get rid of the zeros and display it as 1.552 instead of 1.552000000?
I ask because the real numbers could be different each time when read from the keyboard by user

other times the real number could be  0.50000000
or could be 1.0000000


Please help.

Thanks

ToutEnMasm


raymond

If you know the number of decimals before the trailing zeros, you simply convert it with the required number of decimal places.

However, you may rarely know that in advance. Then the only way is the hard way:
a) convert it with 15 decimal places (or whatever you need as a maximum),
b) find the end of the converted string (the terminating 0),
c) check if the last digit of the string is a "0" character and continue backtracking the string until you find a digit which is not a "0" (the decimal delimiter will also terminate your search),
d) insert the terminating 0 after the last non-"0" digit.
Your string is then ready for display without any trailing "0".
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

etow

Hi

I produce the following code below but it crashes when trying to remove the remaining zeros from the floating point number.   I am not sure why?
Please help me.

Thanks


.686

;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;The MASM32 Floating point library include files.
Include \masm32\fpulib\fpu.inc
IncludeLib \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Const
decimalPlace = 15 ; maximum of 15 decimal places for real10 floating point numbers

.Data
oldText DB "00", 0
newText DB " ", 0
removedZerosText DB ?, 0
removedBlanksText DB ?, 0

Number Real10 ?   ; user floating point number user entered
modifyNumber Byte 100 Dup(?)  ; display real10 string for FpuFLtoA function

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey        ; pause the screen while waiting for user to press any key
             ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

removingExtraZerosString Proto:Real10

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   Input10 procedure will convert input   <<
;<<   from keyboard into real10 numbers      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:DWord
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP

Main Proc

Local WantContinue:DWord

   Mov WantContinue, 0   ; initialize WantContinue to zero

  .While ((WantContinue >= 0) && (WantContinue < -1))
  ; while WantContinue is greater than or equal to 0 And
  ; WantContinue is less than -1 do
  print chr$(13, 10)  ; a carriage return line feed will be outputted to the
                      ; screen
    print chr$("Enter a real Number : ")
    Invoke InputR10, Addr Number

    print chr$(13, 10, " Outputting the real10 floating point Number :  ")
    print real10$ (Number)
    print chr$(13, 10, " by using real10$ function to 6 decimal places .", 13, 10, 13, 10)

    ; FpuFltoA displays real10 floating point number has up to 15 decimal digits
    ; after decimal point and up to 17 characters before the decimal point
    Invoke FpuFLtoA, Addr Number, decimalPlace, Addr modifyNumber, SRC1_REAL Or STR_REG
    Or Eax, Eax
    Jz _Error
    print chr$(" Displaying the real10 floating point Number :  ")
    print Addr modifyNumber
    print chr$(13, 10, " by using FpuFLtoA function to ")
    print str$(decimalPlace)
    print chr$(" decimal places .")
    print chr$(13, 10, 13, 10)

    Invoke removingExtraZerosString, Number
    print str$(removedBlanksText)

    Jmp _Continue

_Error:
    print chr$("Error displaying the floating point number by FpuFLtoA function!")
    print chr$(13, 10, 13, 10)

_Continue:
    Mov WantContinue, sval(input("Enter -1 to quit program : "))
    Invoke ClearScreen
  .EndW

    Ret
Main EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  removingExtraZerosString procedure will remove  <<
;<<  remaining zeros in the real10 floating point    <<
;<<  number                                          <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

removingExtraZerosString Proc RealNumber:Real10

Local counter:DWord

Mov counter, 1
Invoke szLen, Addr RealNumber

.While (counter <= Eax)
Invoke szRep, Addr RealNumber, Addr removedZerosText, oldText, newText
    Inc counter
.EndW

Invoke szRtrim, removedZerosText, removedBlanksText

  Ret
removingExtraZerosString EndP

End start

herge

 Hi etow:

Try this:

TrailZero Proc
    invoke StrLen, esi
    mov ecx,eax
    dec ecx
@@:
    mov al, byte ptr [esi + ecx]
    cmp al,"0"
    jnz @f
    dec ecx
    jnz @B
@@:
    inc ecx
    mov byte ptr [esi + ecx],0
    ret
TrailZero endp


    lea esi, modifyNumber
    call TrailZero
    print addr modifyNumber

  Hope this helps!

// Herge born  Brussels, Belgium May 22, 1907
// Died March 3, 1983
// Cartoonist of Tintin and Snowy

etow


etow

Hi

The complete program is in the attachment to download.
Here is the complete program to remove remaining zeros in text below:


;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\fpulib\fpu.inc
IncludeLib   \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Const
maxDecimalPlace = 15

.Data
Number Real10 ?
modifyNumber Byte 100 Dup(?)

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey        ; pause the screen while waiting for user to press any key
             ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   Input10 procedure will convert input   <<
;<<   from keyboard into real10 numbers      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:DWord
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP

Main Proc

Local WantContinue:DWord
Local stringLength:DWord

   Mov WantContinue, 0   ; initialize WantContinue to zero

  .While ((WantContinue >= 0) && (WantContinue < -1))
  ; while WantContinue is greater than or equal to 0 And
  ; WantContinue is less than -1 do
  print chr$(13, 10)  ; a carriage return line feed will be outputted to the
                      ; screen
    print chr$("Enter a real Number : ")
    Invoke InputR10, Addr Number

    print chr$(13, 10, " Outputting the real10 floating point Number :  ")
    print real10$ (Number)
    print chr$(13, 10, " by using real10$ function .", 13, 10, 13, 10)

    Invoke FpuFLtoA, Addr Number, maxDecimalPlace, Addr modifyNumber, SRC1_REAL Or STR_REG
    Or Eax, Eax
    Jz _Error
    print chr$(" Displaying the real10 floating point Number :  ")
    print Addr modifyNumber
    print chr$(13, 10, " by using FpuFLtoA function to ")
    print str$(maxDecimalPlace)
    print chr$(" decimal places maximum.")
    print chr$(13, 10, 13, 10)

    print chr$(" Removing extra zeros with TrailZero Proc :  ")
    Lea Esi, modifyNumber
    call TrailZero
    print Addr modifyNumber

    Jmp _Continue

_Error:
print chr$(13, 10)
    print chr$(" Error displaying floating point number as string ")
    print chr$("by using FpuFLtoA function!", 13, 10, 13, 10)

_Continue:
    print chr$(13, 10, 13, 10, 13, 10)
    Mov WantContinue, sval(input("Enter -1 to quit program : "))
    Invoke ClearScreen
  .EndW

    print chr$(13, 10)
    Ret
Main EndP

TrailZero Proc
    Invoke StrLen, Esi
    Mov Ecx, Eax
    Dec Ecx
@@:
    Mov Al, Byte Ptr [Esi + Ecx]
    Cmp Al, "0"
    Jnz @F
    Dec Ecx
    Jnz @B
@@:
    Inc Ecx
    Mov Byte Ptr [Esi + Ecx], 0

    Dec Ecx
    .If (Byte Ptr [Esi + Ecx] == ".")
       Mov Byte Ptr [Esi + Ecx], 0
    .EndIf

    ret
TrailZero EndP

[attachment deleted by admin]

etow

Please delete "Local stringLength:DWord"  from the program since there is no use for it.

herge

 Hi Etow:

If You always want a zero after the decimal IE 3.0
try this:

Quote
TrailDot Proc
    invoke StrLen, esi
    mov ecx,eax
    dec ecx
@@:
    movzx eax, byte ptr [esi + ecx]
    cmp al,"."
    jz @f
    ret
@@:
    inc ecx
    mov byte ptr [esi + ecx],"0"
    inc ecx
    mov byte ptr [esi + ecx],0
    ret
TrailDot endp

// Herge born  Brussels, Belgium May 22, 1907
// Died March 3, 1983
// Cartoonist of Tintin and Snowy

herge

 Hi etow:

You have to call TrailZero first!
Before calling TrailDot.


    lea esi, modifyNumber
    call TrailZero
    call TrailDot
// Herge born  Brussels, Belgium May 22, 1907
// Died March 3, 1983
// Cartoonist of Tintin and Snowy

raymond

QuoteYou have to call TrailZero first!

But that would be as long as you don't erase the decimal point with the TrailZero procedure!!! :( :clap:
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

Adamanteus

 Looked on this long discussion and decided to join, as I do it on C by two functions :

rtrim(number, _T('0')); // trim tail zeros
strrdel (number, _T('.')); // delete last pset if is