Initialising attotimedelta with 0.1 seconds

Issue #1 wontfix
Neeraj created an issue

Hi,

Thanks for writing the package. I’m looking to use it in my geophysical data processing package (resistics, resistics.io), which I’m currently re-writing. I read the doc info about attotimedelta, which states:

All arguments are optional and default to 0. All arguments may be ints, longs, or floats, and may be positive or negative.

I’ve been using attotimedelta(seconds=1/4096) and this appears to work well:

>>> from attotime import attotimedelta 
>>> attotimedelta(seconds=1/4096)
attotime.objects.attotimedelta(0, 0, 244, 140.625)    

However, if I try doing something similar with seconds=0.1, I appear to get some trailing numbers

>>> attotimedelta(seconds=0.1)                                      
attotime.objects.attotimedelta(0, 0, 100000, 0.0000000055511151231) 
>>> attotimedelta(seconds=0.1, microseconds=0, nanoseconds=0)       
attotime.objects.attotimedelta(0, 0, 100000, 0.0000000055511151231) 

Finally, trying:

>>> attotimedelta(microseconds=100_000)
attotime.objects.attotimedelta(0, 0, 100000)

I just wanted to double check whether attotimedelta should be able to resolve seconds=0.1 or if I am using it incorrectly?

Thanks

Comments (4)

  1. Brandon Nielsen repo owner

    You correctly identified what is happening. There are a couple of workarounds you may consider:

    First, you could give it Decimals built from strings as indicated in the Stack Overflow post:

    >>> attotimedelta(seconds=Decimal("0.1"))
    attotime.objects.attotimedelta(0, 0, 100000)
    

    It also behaves correctly if given strings:

    >>> attotimedelta(seconds="0.1")  
    attotime.objects.attotimedelta(0, 0, 100000)
    

    Alternatively, you can modify the precision to the level necessary for your use case, but keep in mind the handling of repeated reductions to microseconds may still mean you do not get the ultimate precision you are looking for:

    >>> from decimal import localcontext
    >>> with localcontext() as context:
    ...     context.prec = 35
    ...     attotimedelta(seconds=0.1)
    ... 
    attotime.objects.attotimedelta(0, 0, 100000, 0.0000000055511151231257827)
    attotime.objects.attotimedelta(0, 0, 100000, 0.00000000555111512312578270211815834)
    >>> with localcontext() as context:
    ...     context.prec = 100
    ...     attotimedelta(seconds=0.1)
    

    There may be some improvements to be made by reducing the number of sequential reductions made (or by clever casting to strings?), but I am not currently pursuing it.

    The documentation should be made clearer to indicate Decimal objects are a supported input type.

  2. Neeraj reporter

    Hi, thanks for the response. I ended up changing how I construct the attotimedelta, adding some logic to ensure I only pass floats to nanoseconds and otherwise, pass integers where possible to seconds and microseconds.

    Cheers

  3. Log in to comment