24

My goal is simply to convert a string such as "1.2" to scientific notation without adding additional precision. The problem is that I always end up with superfluous 0s at the end of my output.

>>> input = "1.2" >>> print '{:e}'.format(float(input)) 1.200000e+00 

I'm trying to figure out how to get just 1.2e+00. I realize I can specify precision in my format statement, but I don't want to truncate longer strings unnecessarily. I just want to suppress the training 0s.

I've tried using Decimal.normalize(), which works in all cases, except where e < 2.

>>> print Decimal("1.2000e+4").normalize() 1.2E+4 >>> print Decimal("1.2000e+1").normalize() 12 

So that's better, except I don't want 12, I want 1.2e+1. :P

Any suggestions would be greatly appreciated!

Edit: To clarify, the input value has already been rounded appropriately to a predetermined length that is now unknown. I'm trying to avoid recalculating the appropriate formatting precision.

Basically, I could have input values of "1.23" and "1234.56", which should come out as "1.23e+0" and "1.23456e+3".

I may have to just check how long the input string is and use that to specify a precision manually, but I wanted to check and make sure I just wasn't missing something that could just prevent the exponential format from arbitrarily adding 0s.

8
  • How do you know what the "right" number of digits is? Please update the question with the rule for knowing this. Be sure to cover the 3.33333333 case. Commented Apr 6, 2011 at 20:42
  • @S.Lott: In science we use "significance". So if I have input value of 10 meters I can not give an answer of 3.3333 meters. That's an increase of significance which is illegal. 3.3m would be the correct answer. Commented Apr 6, 2011 at 20:55
  • @nightcracker. But my 3.33333 m/s wasn't an increase in precision. It was 1.0m/3.0s. Both with precisions of just 1 decimal point. Commented Apr 6, 2011 at 20:57
  • 5
    It is. First you measure a wooden stick with a measuring stick only capable of measuring up to one tenths of a meter precise. You measure 1.0m. And with some stopwatch you measure 3.0s. You do some physics and come to a result of 1.0/3.0. Now the result MUST be 0.33 m/s. Why? Because it's bullshit to say that you know the difference between 0.33 and 0.333 m/s (0.003 m/s) while you only measured in tenths of seconds and meters. Commented Apr 6, 2011 at 21:20
  • @nightcracker: My software said 0.33333333. The question is how to format this number in some desirable way. You have a rule. I don't know how to get your rule to match this question. Commented Apr 6, 2011 at 21:27

3 Answers 3

40

You can specify precision in the format:

print '{:.2e}'.format(float(input)) 

This will always give 2 decimals of precision. The amount of precision you want must be determined by yourself. If you need any help with that post in the comments.

Sign up to request clarification or add additional context in comments.

4 Comments

The problem is just that I may not know in the method what precision to expect. Considering using methods here to identify precision and adjust accordingly: stackoverflow.com/questions/3018758/…
Using .2 doesn't work for scientific significant digits: 5.7 * 6.4 = 36.48 but since the inputs both have two digits of significance, the correct output (with two digits of significance) is 36.
@Harvey "The amount of precision you want must be determined by yourself." I never said anything about significant digits, only output precision.
You're correct. I got here by a different search and misread the problem.
9

Just going back through and cleaning up old questions. I ended up solving this by writing a little function to intuit the initial precision of a number and then using it to format the output result.

#used to determine number of precise digits in a string def get_precision(str_value): vals = str_value.split('.') if (vals[0] == '0'): return len(vals[1]) else: return len(str_value) -1 # maintain same precision of incoming string on output text class ExpDecorator(CurrencyDecorator): def get_text(self): text = self.decoratedCurrency.get_text() return ('{:.' + str(get_precision(text)-1) + 'e}').format(float(text)) 

Not really the most elegant solution, but the task was kind of obnoxious to begin with and it got the job done.

2 Comments

You may know this by now, but the formatting language allows this: '{:.{}e}'.format(float(text), get_precision(text)-1)
Unfortunately, this only works if the number is >= 1e-04.
1

It took a bit of tweaking Alex's solution but I wrote a function that would remove all trailing zeros from any number in python.

def remove_trailing_zeros(value): value = str(value) if value.find('e') != -1: vals = value.split('e') e = vals[1] return '{:g}'.format(float(vals[0]))+'e'+e vals = value.split('.') if (vals[0] == '0'): i = 0 while vals[1][i] == '0': i += 1 return '{:.{}e}'.format(float(value), len(vals[1][i:]) - 1) else: j = len(vals[0]) - 1 while vals[0][j] == '0': j -= 1 return '{:.{}e}'.format(float(value), len(vals[0][:j])) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.