0

Hi I have a somewhat strange question. I am converting a list of numbers (which represent physical measurements), where each are reported to some specified accuracy in arbitrary units depending on the study it comes from. Here is an example of what I mean:

[...,105.0,20.0,3.5,4.25,9.78,7.2,7.2] 

These are of course of type:

<type 'numpy.float64'>.

If I print out the last number, for instance:

print list[-1]
>>> 7.2

However, if accessed in this way, I get:

7.2000000000000002

I understand that floats are by default 64 bits, so doing a calculation with them (i.e. - converting this list of measurements) returns a converted value which is 64 bits. Here is an example of the converted values:

[105.27878958,20.0281600192,3.47317185649,4.27596751688,9.82706595042,7.27448290596,7.26291009446]

Accessing them either way (using print or not), returns a 64 bit number. But clearly there is something else going on, otherwise the print function wouldn't really know how to display the true measurement. I would like to report the converted values to the same level of accuracy as the original measurements. Is there a way I can do this in python?

astromax
  • 6,001
  • 10
  • 36
  • 47
  • Take a look [here](http://stackoverflow.com/questions/18915378/rounding-to-significant-figures-in-numpy). Depends if you want to round your numbers or just modify the output by modifying what gets printed or formatting to string accordingly. – Midnighter May 19 '14 at 23:20
  • I want it to be exactly as the measured values. When I explicitly print the number of the converted list, I would like it to print out the number to the same number of digits as the corresponding measured value. – astromax May 19 '14 at 23:24
  • I took a look - all solutions just look like they're rounding to some specified predefined place. – astromax May 19 '14 at 23:25
  • Also, I want to be able to compare eventually. This is what I mean: print list[-1] == 7.2 (which gives me True; I just checked it). – astromax May 19 '14 at 23:26
  • 3
    The `print` function doesn't display a "true measurement", it has some built-in rounding to save our human brains from the horror of the underlying floating-point representations. – roippi May 19 '14 at 23:28
  • 4
    What Every Programmer Should Know About Floating-Point Arithmetic http://floating-point-gui.de/ The point of using Numpy is to have access to algorithms and libraries written in C or even Fortran to manipulate data. This means that the data will be stored in C. If you would like exact precision you may use the Decimal module in the Standard Library however you will get no Numpy-specific speed-up as the data will then be stored as Python objects instead of in C. – mechanical_meat May 19 '14 at 23:36
  • @roippi Well, I understand that. However, the "true" measurement in my example is a physical measurement and was reported as 7.2. I'm using true as what I expect the number to be (though I believe in your sense you're using it as how the number is actually stored - as a 64 bit float). When I store those data in a list, and print it out, it gives me the number as I want it. – astromax May 19 '14 at 23:41
  • Then you will have to either do rounding - because that's what `print` is doing - or simply don't use floats to store your data. – roippi May 19 '14 at 23:43
  • @bernie I'll give that a read over - thanks. – astromax May 19 '14 at 23:49
  • My whole question is: How can I round the same way as print... – astromax May 19 '14 at 23:49
  • People who have put this on hold - read the last sentence in my original post: "I would like to report the converted values to the same level of accuracy as the original measurements. Is there a way I can do this in python?" – astromax May 20 '14 at 02:47

1 Answers1

6

You have three problems:

1) How do I determine the number of decimal places in the input?

If your Python code literally says [...,105.0,20.0,3.5,4.25,9.78,7.2,7.2], you're out of luck. You've already lost the information you need.

If, instead, you have the list of numbers as some kind of input string, then you have the info you need. You probably already have code like:

for line in input_file:
    data = [float(x) for x in line.split(',')]

You need to record the number of places to the right of the decimal before converting to float, for example:

for line in input_file:
    places = [len(x.partition('.')[2]) for x in line.split(',')]
    data = [float(x) for x in line.split(',')]

2) How do I store that information?

That's up to you. Sorry, I can't help you with that one without seeing your whole program.

3) How do I format the output to round to that number of decimal places?

Use the % operator or {}-style formatting, like so:

print '%.*f' % (places[i], data[i]) 
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • This is exactly what I was looking for - Thank you. I do have a data file, so the information should all be there. I'll give this a shot. – astromax May 20 '14 at 01:44