Why is my decimal rounding to 1 significant figure?

Viewed 129

My stopwatch I'm using to execute code is rounding to one significant figure for no apparent reason at all.


FormTime is defined manually from FORM
I've trimmed it down from FORM=[[1, 1, 0, 0, 0], to just include the time for debugging purposes

FORM=[[1], [1.875], [2.25], [4.562], [5.438]]

stopwatch is defined from the following;

import datetime
from math import floor
a = datetime.datetime.now()

while True:
        
    b = datetime.datetime.now()
    c = (b - a)
    roundMicro = floor(c.microseconds/1e3)
    stopwatch = float(str(c.seconds)+'.'+str(roundMicro))

    ...

stopwatch running in loop outputs;

>>> stopwatch
0.0
...
0.123
...
0.2

For example here is the time it's meant to execute (FormTime) vs when it actually executes (Ex which is just stopwatch)

count = 0
a = datetime.datetime.now()

while True:
        
    b = datetime.datetime.now()
    c = (b - a)
    roundMicro = floor(c.microseconds/1e3)
    stopwatch = float(str(c.seconds)+'.'+str(roundMicro))
    

    if FORM[count][0]<=stopwatch:
        
        print(f'FormTime = {FORM[count][0]}', end="")
        print(f'{" "*int(7-len(str(FORM[count][0])))}', end="") #Just decorative spacing in terminal
        print(f'Ex ≈ {stopwatch}') #Ex = Executed @
        count+=1

Returns;

FormTime = 1      Ex ≈ 1.0
FormTime = 1.875  Ex ≈ 1.9
FormTime = 2.25   Ex ≈ 2.3
FormTime = 4.562  Ex ≈ 4.6
FormTime = 5.438  Ex ≈ 5.5

Any idea why it executes when stopwatch = one significant digit?
Or why it's rounding?

  • Don't mind the Exception has occurred: IndexError list index out of range, line 21 this is intended to occur at the end of the demo
1 Answers
roundMicro = floor(c.microseconds/1e3)
stopwatch = float(str(c.seconds)+'.'+str(roundMicro))

These two lines probably aren't what you're expecting. Assume c.microseconds == 3000, you'll get roundMicro = 3 and end up with 1.3 when it should be 1.003.

Reinventing the wheels isn't necessary here unless you're learning about mathematical rounding. Use format strings to get your desired precision (and optionally, layout):

stopwatch = "{:.3f}".format(c.seconds + c.microseconds * 1e-6)
# => 1.003

And if you need the truncated value as a number, you can still call float(stopwatch) to convert the string.

Related