Round negative float numbers to floats [closed] - python

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I am trying to round some negative floating numbers, the format i want is like the below print/format way, not the round. The problem is that the print approach is not "clean", since it outputs a string with spaces, I got this code from another similar question here in Stackoverflow. The question is how to format/round the numbers like the print below. Thank you
theta = 0.33161255787892263
math = 0 + (1-0) * (1-math.cos(theta))**5
round(math,8) # Result: 4.8e-07 #
print("{:18.8f}".format(math)) # Result: ' 0.00000048' #

You say "I want the result of the print but in a float number not string" and "The result returns to a negative power floating point number, i want to keep the decimal format as the string". But you can't do that because you have no control over the internal representation of a float: they are all stored in a binary form of scientific notation. See the Wikipedia article on floating-point numbers for details.
So it doesn't matter whether you do
v = 0.00000048
or
v = 4.8e-07
both of those statements have an identical effect.
Note that many fractional numbers that terminate when written in decimal may repeat when written in binary. The only fractions that terminate when written in binary are of the form n / (2 ** b), where n and b are integers. Thus even an innocuous-looking number like 0.2 doesn't terminate when converted to binary. (See the Wiki link for a fuller explanation). Because of this issue it's generally not a good idea to round floating-point numbers until you've finished all calculations with them.
If you convert a string to float and back again it has to be converted from decimal to binary and back again. So such an operation shouldn't be used in an attempt to "clean up" a number because of the possible rounding errors at each conversion step.
Of course, sometimes you do need to apply rounding to a float that you are going to continue calculating with, but if so, you should proceed with caution and make sure you really do understand what you're doing to your data.
...
There are a few other strange things with the code you posted.
math = 0 + (1-0) * (1-math.cos(theta))**5
Firstly, you should not use the name of a module that you've imported as a variable name. After the above statement is executed math now refers to the result of the calculation, not the math module, so if you tried to do x = math.cos(0.5) you'd get an error. Similarly, don't use int, str, list, etc as variable names.
Secondly, the 0 + (1-0) * is virtually useless. So the above statement could be re-written as
result = (1 - math.cos(theta)) ** 5
And the whole code snippet would become
#! /usr/bin/env python
import math
theta = 0.33161255787892263
result = (1 - math.cos(theta)) ** 5
print round(result, 8)
print("{0:.8f}".format(result))
output
4.8e-07
0.00000048

Related

Check if the length of the range divided by range element has no division remainder [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
The code below shall show a specific comment if the number of elements in the array isn't integer-type number.
It works for dr=0.5 but not for dr=0.1 because print (4%0.1) returns 0.09999999999999978 instead of 0.
How can I change the code to get 4%0.1==0?
import math
limits_real=(-2,2)
dr=0.1
if (limits_real[1]-limits_real[0])%dr!=0:
print ('Inapropriate limits or elements')
It works for dr=0.5 but not for dr=0.1 because print (4%0.1) returns 0.09999999999999978 instead of 0.
Because floating point numbers have limitations that every programmer should know, see this:
https://docs.python.org/3/tutorial/floatingpoint.html
As showed at the end of above documentation, you can use decimal module, which works exacly right but is slower than normal floating point arihtmetics:
from decimal import Decimal
limits_real=(-2,2)
dr = Decimal("0.1")
if (limits_real[1] - limits_real[0]) % dr != 0:
print ('Inapropriate limits or elements')
Note that you should use a str while constructing the Decimal instance, do not use a float.
I found out only this solution :) At least it works
import math
limits_real=(-2,2)
dr=0.1
if (((limits_real[1] - limits_real[0]) * 1000) % (dr * 1000)) / 1000 != 0:
print ('Inapropriate limits or elements')

How to return the fractional part of a number? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
How can I get the fractional part of a number?
For example, I have a list of floats num = [12.73, 9.45] and want to get only the numbers after the decimal point, 73 and 45 in this case. How do I go about doing this?
One approach is using pure(ish) maths.
The short answer:
num = [12.73, 9.45]
[int((f % 1)*100) for f in num]
>>> [73, 44]
Explanation:
The modulo operator returns the remainder once whole division is complete (to over-simplify).
Therefore this, returns the decimal value; the fractional part of the number.
12.73 % 1
>>> 0.7300000000000004
To get the decimal value as a integer, you can use:
int((12.73 % 1)*100)
>>> 73
Just wrap this in a loop for all required values ... and you have the 'short answer' above.
num = [12.73, 9.45];
result = list(map(lambda x: int(str(x).split('.')[1]),num))
print(result)
and want to get only the numbers after the period,
There is no such thing. Numbers don't have digits; the string representation of the numbers has digits. And even then, floating-point numbers are not precise; you may be shown 0.3 in one context and 0.30000000000000004 in another, for the same value.
It sounds like what you are actually after is the fractional part of the numbers. There are many ways to do this, but they all boil down the same idea: it is the result when you divide (as a floating-point number) the input by 1.
For a single value, it looks like:
fractional_part = value % 1.0
or
# This built-in function performs the division and gives you
# both quotient and remainder.
integer_part, fractional_part = divmod(value, 1.0)
or
import math
fractional_part = math.fmod(value, 1.0)
or
import math
# This function is provided as a special case.
# It also gives you the integer part.
# Notice that the results are the other way around vs. divmod!
fractional_part, integer_part = math.modf(value)
To process each value in a list in the same way, use a list comprehension.

How to convert a string of a decimal number from any base to a decimal number? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I'm looking to write a function that can convert a string with a given base to a decimal number.
Let's say the function is convert calling convert should give me the following output
convert('3.14', base=10) ~= 3.14
convert('100.101', base=2) == 4.625
To convert floating-point numbers from one base to another, you can just break the number in half, handle the whole and the part separately, and then join them back together.
num = '100.101'
base = 2
# split into whole and part
whole = num[:num.index('.')]
part = num[num.index('.') + 1:]
# get the logarithmic size of the part so we can treat it as a fraction
# e.g. '101/1000'
denom = base ** len(part)
# use python's built-in base conversion to convert the whole numbers
# thanks #EthanBrews for mentioning this
b10_whole = int(whole, base=base)
b10_part = int(part, base=base)
# recombine the integers into a float to return
b10_num = b10_whole + (b10_part / denom)
return b10_num
Thanks to the other answerer #EthanBrews for mentioning that integer stuff was already built-in. Unfortunately the same construction doesn't same to exist for float.
Python supports already. Simply use my_int = int(str, base)

Decimal points in python [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have some floating point values, these all values are dynamically generated:
float_a = 12.200
float_b = 14.0
float_c = 14.01880
I want to remove the decimal point from them.
Expected Result
"12200"
"140"
"1401880"
I must be careful as these are not fixed-point values and I don't have any control on how many decimal places my input will go up to. More examples from the comments:
1.10
1.110
2.0
2.1340
Expected result:
"110"
"1110"
"20"
"21340"
This question seems to be a permutation of another question that has already been answered:
The concept of leading zeros is a display concept, not a numerical
one. You can put an infinite number of leading zeros on a number
without changing its value. Since it's not a numeric concept, it's not
stored with the number.
You have to decide how many zeros you want when you convert the number
to a string. You could keep that number separately if you want.
SOURCE: Python Force python to keep leading zeros of int variables
It looks like the only way to do what you are asking is if your initial "Float" is in string form, otherwise the trailing 0's will be dropped. If you manage to get the "Float" as a string (before it ever becoming a Float), then you can use the int('12.200'.replace('.', '')) method mentioned above
If you're starting off with a string, which I think you are. I would use something like:
>>> int('12.200'.replace('.',''))
12200
It just removes the . and parses the resulting string as an int. Otherwise just cast whatever you have to str first.
It is just a formatting issue. Either of these work to get trailing zeroes:
>>> '{:.3f}'.format(1.2)
'1.200'
>>> '%0.3f' % (1.2,)
'1.200'
Then:
>>> '{:.3f}'.format(12.2).replace('.','')
'12200'
To get what you want from your examples:
vals=(1.10, 1.110, 2.0, 2.134)
def wid(f):
w=1
while True:
s='{:.{w}f}'.format(f, w=w)
if s[-1]=='0' or w>5:
break
w+=1
return w
for e in vals:
s='{:.{w}f}'.format(e, w=wid(e)).replace('.','')
print '{:10} => {}'.format(e, s)
Prints:
1.1 => 110
1.11 => 1110
2.0 => 20
2.134 => 21340
If you want to remove the decimal, why not multiply by 1000?
float_a = 12.200
print str(int(float_a*1000))
When you have
float_a = 1.110
float_b = 1.1100
float_c = 1.11000
Python is discarding the trailing zeros, and the above 3 are the exact same. These trailing zeros are non-significant digits, and so if you want to actually preserve them, your original data type will need to be a String.
If you make that change, then it is simple to do
float_a = "1.110"
print float_a.replace('.', '') # "1110"
If you're asking how to turn float_a = 12.200 into the string "12200", simply multiply it by 1000 before converting it into a string, for example:
print(str(float_a * 1000))
However, if the number contains more than 4 decimal places, you'll still have decimals.
However, since you're talking about it "always removing the 0's", I suspect you may have missed a . in your expected output. In this case, to display a float with a fixed number of decimals, just use Python's built-in string formatting:
float_a = 12.200
expected_result = '%.2f' % float_a
print expected_result
> 12.20
If this doesn't make sense, please clarify your question a bit and I'll edit! :)
Edit
Upon your further clarification of the question, it seems that you want to define a float with trailing zeros and have them preserved and the float converted to a string with the leading zeros preserved. I'm afraid this is impossible if your input type is float, since float won't preserve those trailing zeros to begin with:
In [1]: float_a = 3.1400
In [2]: float_a
Out[2]: 3.14
This is a "limitation" of the data type and there's nothing you can do about it. You want a fixed-point type or something to handle "decimal numbers", not a float.

Truncation in python

How can we truncate (not round) the cube root of a given number after the 10th decimal place in python?
For Example:
If number is 8 the required output is 2.0000000000 and for 33076161 it is 321.0000000000
Scale - truncate - unscale:
n = 10.0
cube_root = 1e-10 * int(1e10 * n**(1.0/3.0))
You should only do such truncations (unless you have a serious reason otherwise) while printing out results. There is no exact binary representation in floating point format, for a whole host of everyday decimal values:
print 33076161**(1.0/3.0)
A calculator gives you a different answer than Python gives you. Even Windows calculator does a passable job on cuberoot(33076161), whereas the answer given by python will be minutely incorrect unless you use rounding.
So, the question you ask is fundamentally unanswerable since it assumes capabilities that do not exist in floating point math.
Wrong Answer #1: This actually rounds instead of truncating, but for the cases you specified, it provides the correct output, probably due to rounding compensating for the inherent floating point precision problem you will hit in case #2:
print "%3.10f" % 10**(1.0/3.0)
Wrong Answer #2: But you could truncate (as a string) an 11-digit rounded value, which, as has been pointed out to me, would fail for values very near rollover, and in other strange ways, so DON'T do this:
print ("%3.11f" % 10**(1.0/3.0))[:-1]
Reasonably Close Answer #3: I wrote a little function that is for display only:
import math
def str_truncate(f,d):
s = f*(10.0**(d))
str = `math.trunc(s)`.rstrip('L')
n = len(str)-d
w = str[0:n]
if w=='':
w='0'
ad =str[n:d+n]
return w+'.'+ad
d = 8**(1.0/3.0)
t=str_truncate(d,10)
print 'case 1',t
d = 33076161**(1.0/3.0)
t=str_truncate(d,10)
print 'case 2',t
d = 10000**(1.0/3.0)
t=str_truncate(d,10)
print 'case 3',t
d = 0.1**(1.0/3.0)
t=str_truncate(d,10)
print 'case 4',t
Note that Python fails to perform exactly as per your expectations in case #2 due to your friendly neighborhood floating point precision being non-infinite.
You should maybe know about this document too:
What Every Computer Scientist Should Know About Floating Point
And you might be interested to know that Python has add-ons that provide arbitary precision features that will allow you to calculate the cube root of something to any number of decimals you might want. Using packages like mpmath, you can free yourself from the accuracy limitations of conventional floating point math, but at a considerable cost in performance (speed).
It is interesting to me that the built-in decimal unit does not solve this problem, since 1/3 is a rational (repeating) but non-terminating number in decimal, thus it can't be accurately represented either in decimal notation, nor floating point:
import decimal
third = decimal.Decimal(1)/decimal.Decimal(3)
print decimal.Decimal(33076161)**third # cuberoot using decimal
output:
320.9999999999999999999999998
Update: Sven provided this cool use of Logs which works for this particular case, it outputs the desired 321 value, instead of 320.99999...: Nifty. I love Log(). However this works for 321 cubed, but fails in the case of 320 cubed:
exp(log(33076161)/3)
It seems that fractions doesn't solve this problem, but I wish it did:
import fractions
third = fractions.Fraction(1,3)
def cuberoot(n):
return n ** third
print '%.14f'%cuberoot(33076161)
num = 17**(1.0/3.0)
num = int(num * 100000000000)/100000000000.0
print "%.10f" % num
What about this code .. I have created it for my personal use. although it is so simple, it is working well.
def truncation_machine(original,edge):
'''
Function of the function :) :
it performs truncation operation on long decimal numbers.
Input:
a) the number that needs to undergo truncation.
b) the no. of decimals that we want to KEEP.
Output:
A clean truncated number.
Example: original=1.123456789
edge=4
output=1.1234
'''
import math
g=original*(10**edge)
h=math.trunc(g)
T=h/(10**edge)
print('The original number ('+str(original)+') underwent a '+str(edge)+'-digit truncation to be in the form: '+str(T))
return T

Categories

Resources