Python : Conversion of float to string keeping all digits of decimal place - python

I have a task to count the digits after decimal place.
For which I am using the below code :
str(string_name)[::-1].find('.')
But while converting float to string, it is removing the trailing zeroes :
my_string = 16.520440
print(str(my_string ))
output - '16.52044'
expected output - '16.520440'

Since that trailing zero is not a significant digit, there is no way you can do this within the given paradigm. Floats are stored by value, not by the visual representation of the original input. For instance:
my_string_1 = 16.52044
my_string_2 = 16.520440
my_string_3 = 16.5204400
my_string_4 = 016.5204400
All assign exactly the same value to the LHS variable: they have the same binary representation. Leading and trailing zeros do not, by definition, affect this value. There is no way to differentiate the original input from the stored value.
If you want some such effect, then you need to use some other form of original value that incorporates that information. For instance, you could add a second variable that denotes the quantity of significant decimal places -- which is the opposite of what you're trying to achieve -- or perhaps make the original input a string, from which you could derive that information.

Related

0's in the beginning are being skipped & I'm not sure how to fix it

The output value is not including the 0's in the beginning, can someone help me fix the problem?
def bitwiseOR(P, Q):
return bin(P | Q)
bitwiseOR(0b01010111, 0b00111000)
OUTPUT: '0b1111111'
The leading zeroes are just for representation, so you can utilize Format Specification Mini-Language to display them as you wish:
Format string:
# Includes 0b prefix
0{length} Pad leading zeroes so total length is length
def bitwiseOR(P, Q, length=10):
return format(P | Q, f'#0{length}b')
x = bitwiseOR(0b01010111, 0b00111000)
# 0b01111111
print(x)
Leading zeros are a property of the string you produce, not the number. So, for example, if you're looking for a way to make the following two calls produce different results, that's not possible:1
bitwiseOR(0b01010111, 0b00111000)
bitwiseOR( 0b1010111, 0b111000)
However, if you can provide the number of digits separately, then you can do this using the format() function. It accepts a second argument which lets you customize how the number is printed out using the format spec. Based on that spec, you can print a number padded with zeros to a given width like this:
>>> format(127, '#010b')
'0b01111111'
Here the code consists of four pieces:
# means apply the 0b prefix at the beginning
0 means pad with leading zeros
10 means the total length of the resulting string should be at least 10 characters
b means to print the number in binary
You can tweak the format code to produce your desired string length, or even take the length from a variable.
1Well... technically there is a way to make Python re-read its own source code and possibly produce different results that way, but that's not useful in any real program, it's only useful if you want to learn something about how the Python interpreter works.

How can I convert a float in a str without losing significant figures?

I want to convert the number 0.054000 in a str, but when I write srt(0.054000) I get '0.054'. I need to get '0.054000'. How can I do it?
I have a data file with numbers as my example (0.054000). I need to count the digits of each number. I don't know how to read that number in a way that I count seven digits, for instance.
I think that Dan Patterson's method is the only way to do it reliably - python makes no differentiation between .0054 and .054000: e.g.
>>> .0054 is .0054000
True
Thus you will probably have to simply specify the number of digits you have in sig figs, either using his method or (str(.0054000) + "0"*number_of_sig_figs).
A format specifier starts with a colon and then may contain any of the terms shown
in brackets in the following (each of the terms is optional)
: [[fill]align] [sign] [#] [0] [width] [,] [.precision] [type]
A brief description of the [.precision] is provided below.
.precision: Maximum number of characters for strings (integer); number of digits of
precision for floats. For f, F, e, and E type specifiers this is the number
of digits to the right of the decimal point.
We can use this to specify the precision of our float value:
a=0.540000
print("{:06f}".format(a))
This gives the desired output:
0.540000
Hope this was helpful!

fixed field width for float python [duplicate]

I read a lot of discussion about this on SE, but still can't find the right one.
I want to plot some numbers, of various lengths, with the same number of digits.
For example I have: 12.345678, 1.2345678. Now, since I have to plot them with their error, I want that each one has a different format, in order that they are significant.
So, I want to plot them with a variable number of decimals. In my case, it makes no sense to plot 23.45678+/-1.23456 but better is 23.4+/-1.2. On the other hand, I need that 1.234567+/-0.034567 becomes 1.23+/-0.03.
So, let's say, I want to plot all the numbers with a fixed width, could be 3 digits in total plus the comma. I should use something like '%1.1f' %num, but I can't find the right way. How can I do that?
I recommend defining a class that interprets a string formatter to give what you want.
Inside that class, you determine the length of the integer portion of your float and use that to define the appropriate string format.
In a nutshell, the class creates a formatter like '{:4.1f}' if your input is 12.345 (because you have two digits before the decimal separator) and {:4.2f} if your input it 1.2345 (because you have only one digit before the decimal separator). The total number of digits (4in this example) is provided as an input.
The new formatter is: {:nQ} where n is the total number of digits (so in the above example, you'd specify {:4Q}to get the output you want.
Here's the code:
import math
class IntegerBasedFloat(float):
def __format__(self, spec):
value = float(self)
# apply the following only, if the specifier ends in Q
# otherwise, you maintain the original float format
if spec.endswith('Q'):
# split the provided float into the decimal
# and integer portion (for this math is required):
DEC, INT = math.modf(value)
# determine the length of the integer portion:
LEN = len(str(abs(int(INT))))
# calculate the number of available decimals
# based on the overall length
# the -1 is required because the separator
# requires one digit
DECIMALS = int(spec[-2]) - LEN - 1
if DECIMALS < 0:
print 'Number too large for specified format'
else:
# create the corresponding float formatter
# that can be evaluated as usual:
spec = spec[-2] + '.' + str(DECIMALS) + 'f'
return format(value, spec)
DATA = [12.345, 2.3456, 345.6789]
print '{:4Q}'.format(IntegerBasedFloat(DATA[0]))
print '{:4Q}'.format(IntegerBasedFloat(DATA[1]))
print '{:4Q}'.format(IntegerBasedFloat(DATA[2]))
print 'This is a "custom" float: {:5Q} and a "regular" float: {:5.3f}'.format(IntegerBasedFloat(12.3456),12.3456)
The output should be:
12.3
2.35
346
This is a "custom" float: 12.35 and a "regular" float: 12.346
This answer is inspired by:
- splitting a number into the integer and decimal parts in python
- Add custom conversion types for string formatting

Fixed digits number in floats

I read a lot of discussion about this on SE, but still can't find the right one.
I want to plot some numbers, of various lengths, with the same number of digits.
For example I have: 12.345678, 1.2345678. Now, since I have to plot them with their error, I want that each one has a different format, in order that they are significant.
So, I want to plot them with a variable number of decimals. In my case, it makes no sense to plot 23.45678+/-1.23456 but better is 23.4+/-1.2. On the other hand, I need that 1.234567+/-0.034567 becomes 1.23+/-0.03.
So, let's say, I want to plot all the numbers with a fixed width, could be 3 digits in total plus the comma. I should use something like '%1.1f' %num, but I can't find the right way. How can I do that?
I recommend defining a class that interprets a string formatter to give what you want.
Inside that class, you determine the length of the integer portion of your float and use that to define the appropriate string format.
In a nutshell, the class creates a formatter like '{:4.1f}' if your input is 12.345 (because you have two digits before the decimal separator) and {:4.2f} if your input it 1.2345 (because you have only one digit before the decimal separator). The total number of digits (4in this example) is provided as an input.
The new formatter is: {:nQ} where n is the total number of digits (so in the above example, you'd specify {:4Q}to get the output you want.
Here's the code:
import math
class IntegerBasedFloat(float):
def __format__(self, spec):
value = float(self)
# apply the following only, if the specifier ends in Q
# otherwise, you maintain the original float format
if spec.endswith('Q'):
# split the provided float into the decimal
# and integer portion (for this math is required):
DEC, INT = math.modf(value)
# determine the length of the integer portion:
LEN = len(str(abs(int(INT))))
# calculate the number of available decimals
# based on the overall length
# the -1 is required because the separator
# requires one digit
DECIMALS = int(spec[-2]) - LEN - 1
if DECIMALS < 0:
print 'Number too large for specified format'
else:
# create the corresponding float formatter
# that can be evaluated as usual:
spec = spec[-2] + '.' + str(DECIMALS) + 'f'
return format(value, spec)
DATA = [12.345, 2.3456, 345.6789]
print '{:4Q}'.format(IntegerBasedFloat(DATA[0]))
print '{:4Q}'.format(IntegerBasedFloat(DATA[1]))
print '{:4Q}'.format(IntegerBasedFloat(DATA[2]))
print 'This is a "custom" float: {:5Q} and a "regular" float: {:5.3f}'.format(IntegerBasedFloat(12.3456),12.3456)
The output should be:
12.3
2.35
346
This is a "custom" float: 12.35 and a "regular" float: 12.346
This answer is inspired by:
- splitting a number into the integer and decimal parts in python
- Add custom conversion types for string formatting

How do I preserve leading zeros in Python integers for string formatting

I have what I believe to be a simple question. I have the following code and the output is not what I expect:
import socket
import time
r=031508.78
h=373309.9
z=0
mes='"TSRA %s %s %s\r\n"'%(r,h,z)
print mes
My problem is that r prints as '31508.78' and I want '031508.78'. How I get preserve the leading zero?
The 0 in front of the number is not important for python, because numbers have no leading 0s. You can use:
print '%09.2f'%r
I prefer the new string format mini language. I find it more intuitive.
r = 31508.78
h = 373309.9
z = 0
print '"TSRA {0: 011.3f} {1: 011.3f} {2}"\r\n'.format(r, h, z)
print '{0: 011.3f}\n{1: 011.3f}\n{2: 011.3f}'.format(r, h, z)
{0: 011.3f} 0: indicates the first item (r). 011 tells the formatter that there will be 11 characters including the decimal point and a place holder for a negative sign. By placing a 0 in front the formatter will pad the space with leading zeros. Finally, .3f indicates the precision and a fixed number of places after the decimal point.
Yields:
"TSRA 031508.780 373309.900 0"
031508.780
373309.900
000000.000
I don't think there is any way to store a number with a leading zero in python.
This leaves you with two ways:
1) Make r a string i.e. r="031408.78"
I think this is the best method for you as you can do all the arithmetic you want to do (using the implicit typecasting of python) and see the number appended with a 0 wherever you use it.
2) If you simply want to print the number with leading zeros consider using this
print "%09.2f' % r #for this you need the length of the number
For Python, there is no difference in the following things:
31508.78
031508.78
0000000031508.78
31508.7800000000000
0000000000000031508.7800000000000
Those are all valid representations of the exact same number, which is canonically represented by 31508.78, which is essentially just a convention. Different representations are possible too, and actually, the number is represented in a way that’s described by the IEEE-754 standard.
So, when you want that leading zero, you have to tell Python explicitely to put it there because it simply doesn’t know about it. You just used one of many valid representations to specify that one number which default string representation does not include leading zeroes.
The best way to do this is using string formatting, which comes in two flavors. The old style flavor, using the % operator, and the newer str.format function:
>>> '%09.2f' % 31508.78
'031508.78'
>>> '{:09.2f}'.format(31508.78)
'031508.78'
Or, if you don’t actually want a number, you could also just specify the number as a string to begin with, which of course keeps the leading zero.

Categories