SteveO250k
SteveO250k

Reputation: 59

How to get a list of decimals in python 3

No, this is not a duplicate and the link above is specifically what I was referring to as not the correct answer. That link, and my post here specifically ask about producing a Decimal list. But the "answer" produces a float list.

The correct answer is to use Decimal parameters with np.arange as in `x_values = np.arange(Decimal(-2.0), Decimal(2.0), Decimal(0.1)) Thanks https://stackoverflow.com/users/2084384/boargules

I believe this may be answered elsewhere, but the answers I've found seem wrong. I want a list of decimals (precision = 1 decimal place) from -2 to 2. -2, -1.9, -1.8 ... 1.8, 1.9, 2.0

When I do:

import numpy as np
x_values = np.arange(-2,2,0.1)
x_values

I get:

array([ -2.00000000e+00,  -1.90000000e+00,  -1.80000000e+00, ...

I tried:

from decimal import getcontext, Decimal

getcontext().prec = 2
x_values = [x for x in np.around(np.arange(-2, 2, .1), 2)]
x_values2 = [Decimal(x) for x in x_values]
x_values2

I get:

[Decimal('-2'),
 Decimal('-1.899999999999999911182158029987476766109466552734375'),
 Decimal('-1.8000000000000000444089209850062616169452667236328125'), ...

I'm running 3.6.3 in jupyter notebook.

Update: I changed the ranges from 2 to 2.0. This improved the result, but I still get a rounding error:

import numpy as np
x_values = np.arange(-2.0, 2.0, 0.1)
x_values

Which produces:

-2.00000000e+00,  -1.90000000e+00,  -1.80000000e+00, ...
 1.00000000e-01,   1.77635684e-15,   1.00000000e-01, ...
 1.80000000e+00,   1.90000000e+00

Note 1.77635684e-15 may be an incredibly small number, but it's NOT zero. A test for zero will fail. Therefore the output is wrong.

My response to the duplicate assertion. As you can see by my results the answer at How to use a decimal range() step value? does not produce the same results I'm seeing with a different range. Specifically floats are still being returned and not rounded and 1.77635684e-15 is not equal to zero.

Upvotes: 2

Views: 9145

Answers (2)

DalyaG
DalyaG

Reputation: 3117

From numpy docs -

import numpy as np
np.set_printoptions(suppress=True)

will make sure that "always print floating point numbers using fixed point notation, in which case numbers equal to zero in the current precision will print as zero"

In[2]: import numpy as np

In[3]: np.array([1/50000000])
Out[3]: array([2.e-08])

In[4]: np.set_printoptions(suppress=True)
In[5]: np.array([1/50000000])
Out[5]: array([0.00000002])

In[6]: np.set_printoptions(precision=6)
In[7]: np.array([1/50000000])
Out[7]: array([0.])

In[8]: x_values = np.arange(-2,2,0.1)
In[9]: x_values
Out[9]: 
array([-2. , -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3, -1.2, -1.1, -1. ,
       -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1,  0. ,  0.1,
        0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ,  1.1,  1.2,
        1.3,  1.4,  1.5,  1.6,  1.7,  1.8,  1.9])

Upvotes: 0

hpaulj
hpaulj

Reputation: 231395

The discussion and duplicate dance around a simple solution:

In [177]: np.arange(Decimal('-2.0'), Decimal('2.0'), Decimal('0.1')) 
Out[177]: 
array([Decimal('-2.0'), Decimal('-1.9'), Decimal('-1.8'), Decimal('-1.7'),
       Decimal('-1.6'), Decimal('-1.5'), Decimal('-1.4'), Decimal('-1.3'),
       Decimal('-1.2'), Decimal('-1.1'), Decimal('-1.0'), Decimal('-0.9'),
       Decimal('-0.8'), Decimal('-0.7'), Decimal('-0.6'), Decimal('-0.5'),
       Decimal('-0.4'), Decimal('-0.3'), Decimal('-0.2'), Decimal('-0.1'),
       Decimal('0.0'), Decimal('0.1'), Decimal('0.2'), Decimal('0.3'),
       Decimal('0.4'), Decimal('0.5'), Decimal('0.6'), Decimal('0.7'),
       Decimal('0.8'), Decimal('0.9'), Decimal('1.0'), Decimal('1.1'),
       Decimal('1.2'), Decimal('1.3'), Decimal('1.4'), Decimal('1.5'),
       Decimal('1.6'), Decimal('1.7'), Decimal('1.8'), Decimal('1.9')],
      dtype=object)

Giving float values to Decimal does not work well:

In [180]: np.arange(Decimal(-2.0), Decimal(2.0), Decimal(0.1)) 
Out[180]: 
array([Decimal('-2'), Decimal('-1.899999999999999994448884877'),
       Decimal('-1.799999999999999988897769754'),
       Decimal('-1.699999999999999983346654631'),

because Decimal(0.1) just solidifies the floating point inprecision of 0.1:

In [178]: Decimal(0.1)
Out[178]: Decimal('0.1000000000000000055511151231257827021181583404541015625')

Suggested duplicate: How to use a decimal range() step value?

Upvotes: 1

Related Questions