a
    ߙfb\                     @   s   d Z ddlZddlZddlmZ dddZdddZdd Z	d	d
 Z
dd ZdZd ddZd!ddZd"ddZdd Zdd Zdd Zdd ZeeZeeZeeZejeddZejeddZdS )#ac  Time utilities.

In particular, routines to do basic arithmetic on numbers represented by two
doubles, using the procedure of Shewchuk, 1997, Discrete & Computational
Geometry 18(3):305-363 -- http://www.cs.berkeley.edu/~jrs/papers/robustr.pdf

Furthermore, some helper routines to turn strings and other types of
objects into two values, and vice versa.
    Nc                 C   s   t | |\}}|dur>t||\}}||| 7 }t ||\}}|dur|| }t||\}}	t || \}
}||7 }||	8 }|
| | }t ||\}}t|}t || \}}||| 7 }t|}||7 }t || \}}||| 7 }||fS )a,  Return the sum of ``val1`` and ``val2`` as two float64s.

    The returned floats are an integer part and the fractional remainder,
    with the latter guaranteed to be within -0.5 and 0.5 (inclusive on
    either side, as the integer is rounded to even).

    The arithmetic is all done with exact floating point operations so no
    precision is lost to rounding error.  It is assumed the sum is less
    than about 1e16, otherwise the remainder will be greater than 1.0.

    Parameters
    ----------
    val1, val2 : array of float
        Values to be summed.
    factor : float, optional
        If given, multiply the sum by it.
    divisor : float, optional
        If given, divide the sum by it.

    Returns
    -------
    day, frac : float64
        Integer and fractional part of val1 + val2.
    N)two_sumtwo_productnpround)val1val2factordivisorZsum12Zerr12ZcarryZq1Zp1Zp2Zd1Zd2Zq2dayZextraZfracZexcess r   1lib/python3.9/site-packages/astropy/time/utils.pyday_frac   s*    

r   c                 C   s   |dur0t | \}}t |\}}|| || fS z| jtj}W n" tyd   | tjdf Y S 0 |dkrzt| jdS |dkrt| jd|dS tj| j}t| jd|dS dS )a  Like ``day_frac``, but for quantities with units of time.

    The quantities are separately converted to days. Here, we need to take
    care with the conversion since while the routines here can do accurate
    multiplication, the conversion factor itself may not be accurate.  For
    instance, if the quantity is in seconds, the conversion factor is
    1./86400., which is not exactly representable as a float.

    To work around this, for conversion factors less than unity, rather than
    multiply by that possibly inaccurate factor, the value is divided by the
    conversion factor of a day to that unit (i.e., by 86400. for seconds).  For
    conversion factors larger than 1, such as 365.25 for years, we do just
    multiply.  With this scheme, one has precise conversion factors for all
    regular time units that astropy defines.  Note, however, that it does not
    necessarily work for all custom time units, and cannot work when conversion
    to time is via an equivalency.  For those cases, one remains limited by the
    fact that Quantity calculations are done in double precision, not in
    quadruple precision as for time.
    N        g      ?   )r   )r	   )	quantity_day_fracZunittour
   	ExceptionZto_valuer   value)r   r   Zres11Zres12Zres21Zres22r   r	   r   r   r   r   K   s    r   c                 C   s4   | | }||  }|| }|| }| | }||| fS )a  
    Add ``a`` and ``b`` exactly, returning the result as two float64s.
    The first is the approximate sum (with some floating point error)
    and the second is the error of the float64 sum.

    Using the procedure of Shewchuk, 1997,
    Discrete & Computational Geometry 18(3):305-363
    http://www.cs.berkeley.edu/~jrs/papers/robustr.pdf

    Returns
    -------
    sum, err : float64
        Approximate sum of a + b and the exact floating point error
    r   )abxZebZear   r   r   r   v   s    r   c                 C   sh   | | }t | \}}t |\}}|| }|| }|| }	||	8 }|| }
||
8 }|| }|| }||fS )a  
    Multiple ``a`` and ``b`` exactly, returning the result as two float64s.
    The first is the approximate product (with some floating point error)
    and the second is the error of the float64 product.

    Uses the procedure of Shewchuk, 1997,
    Discrete & Computational Geometry 18(3):305-363
    http://www.cs.berkeley.edu/~jrs/papers/robustr.pdf

    Returns
    -------
    prod, err : float64
        Approximate product a * b and the exact floating point error
    )split)r   r   r   ahalZbhZblZy1yZy2Zy3Zy4r   r   r   r      s    r   c                 C   s(   d|  }||  }|| }| | }||fS )z
    Split float64 in two aligned parts.

    Uses the procedure of Shewchuk, 1997,
    Discrete & Computational Geometry 18(3):305-363
    http://www.cs.berkeley.edu/~jrs/papers/robustr.pdf

    g     Ar   )r   cZabigr   r   r   r   r   r      s
    	r   "   c                 C   sl   |d u r| j d}n,t| j |j }| j|dd} |j|dd}t| |\}}|jtdd|jtddfS )Nr   F)copy)Zdtypetyper   Zresult_typeastyper   float)r   r   Z	best_typeifr   r   r   longdouble_to_twoval   s    r$   c                 C   sX   t  0}t|_t | }t|}|| }W d    n1 s>0    Y  t|t|fS N)decimallocalcontext_enough_decimal_placesprecDecimalr   r!   )r   r   ctxdr"   r#   r   r   r   decimal_to_twoval1   s    

&r-   c                 C   s   t | dS Nascii)r-   decoder   r   r   r   r   bytes_to_twoval1   s    r2   c                 C   s   |  tj| tj S r%   )r    r   Z
longdoubler1   r   r   r   twoval_to_longdouble   s    r3   c                 C   sF   t  *}t|_t | t | W  d    S 1 s80    Y  d S r%   )r&   r'   r(   r)   r*   )r   r   r+   r   r   r   twoval_to_decimal1   s    
r4   c                 C   s>   |dkrt | S tt| ||d}|d dkr:|d7 }|S )Nr   0.)strformatr4   strip)r   r   fmtresultr   r   r   twoval_to_string1   s    r=   c                 C   s   t | ||dS r.   )r=   encode)r   r   r;   r   r   r   twoval_to_bytes1   s    r?   r;   )Zexcluded)NN)N)N)N)N)__doc__r&   Znumpyr   Zastropy.unitsZunitsr   r   r   r   r   r   r(   r$   r-   r2   r3   r4   r=   r?   Z	vectorizeZdecimal_to_twovalZbytes_to_twovalZtwoval_to_decimalZtwoval_to_stringZtwoval_to_bytesr   r   r   r   <module>   s*   	
9
+

	



