python floating point, why is the print result different (examples given)? - list

a = (random.random(), random.random())
print(a)
print(a[0])
the result is:
(0.4817527913069962, 0.7017598562799067)
0.481752791307
What extra is happening behind printing a tuple(similar behavior for list)? Why is there extra fraction?
Thanks a lot.
BTW, this is python 2.7

What you are seeing is the difference between the formatting choices made by str(float) and repr(float). In Python 2.x, str(float) returns 12 digits while repr(float) returns 17 digits. In its interactive mode, Python uses str() to format the result. That accounts for the 12 digits of precision when formatting a float. But when the result is a tuple or list, the string formatting logic uses repr() to format each element.
The output of repr(float) must be able to be converted back to the original value. Using 17 digits of precision guarantees that behavior. Python 3 uses a more sophisticated algorithm that returns the shortest string that will round-trip back to the original value. Since repr(float) frequently returns a more friendly appearing result, str(float) was changed to be the same as repr(float).

Related

powerquery: extra digits added to number when importing table

Glad to ask a question here again after more than 10 years (last one was about BASH scripting, now as I'm in corporate, guess what... it's about excel ;) )
here it's my question/issue:
I am importing data with powerquery for further analysis
I have discovered is that the values imported contains extradigits not present in the original table.
I have googled for this problem but I have not been able to find an explanation nor a solution ( a similar issue is this one this one , more than one year old, but with no feedback from Microsoft )
(columns are formatted as text in the screenshot but the issue is still present even if formatted as number)
The workaround I am using now, but I am not happy with that is the following:
I "increased decimal" to make sure all my digits are captured (in my source the entries do not have all the same significant digits),
saved as csv
imported impacted columns as number
convert columns as text (for future text match
I am really annoyed by this unwanted and unpredictable behaviour of excel.
I see a serious issue of data integrity, if we cannot rely on the powerquery/powerbi platform to maintain accurate queries, I wonder why would be use it
adding another screenshot to clarify that changing the source format to text does not solve the problem
another screenshot added following #David Bacci comments:
I think I wrongfully assumed my data was stored as text in the source, can you confirm?
If you are exporting and importing as text, then this will not happen. If you convert to number, you will lose precision. From the docs (my bold):
Represents a 64-bit (eight-byte) floating-point number. It's the most
common number type, and corresponds to numbers as you usually think of
them. Although designed to handle numbers with fractional values, it
also handles whole numbers. The Decimal Number type can handle
negative values from –1.79E +308 through –2.23E –308, 0, and positive
values from 2.23E –308 through 1.79E + 308. For example, numbers like
34, 34.01, and 34.000367063 are valid decimal numbers. The largest
precision that can be represented in a Decimal Number type is 15
digits long. The decimal separator can occur anywhere in the number.
The Decimal Number type corresponds to how Excel stores its numbers.
Note that a binary floating-point number can't represent all numbers
within its supported range with 100% accuracy. Thus, minor differences
in precision might occur when representing certain decimal numbers.
BTW, you should probably accept some of the good answers from your previous questions from 10 years ago.

Airtable If-statement outputting NaN

I'm using an If-statement to assign integers to strings from another cell. This seems to be working, but if I reference these columns, I'm getting a NaN value. This is my formula below. I tried adding INT() around the output values, but that seemed to break everything. Am I missing something?
IF(FIND('1',{Functional response}),-4,
IF(FIND('2',{Functional response}),-2,
IF(FIND('3',{Functional response}),0,
IF(FIND('4',{Functional response}),2,
IF(FIND('5',{Functional response}),4,"")))))
Assuming Functional response can only store a number 1 to 5 as a string a simple option in excel would be to first convert the string to a number and then use the choose function to assign a value. this works as the numbers are are sequential integers. Assuming Cell K2 has the value of Functional response, your formula could be:
=CHOOSE(--K2,-4,-2,0,2,4)
=CHOOSE(K2+0,-4,-2,0,2,4)
=CHOOSE(K2-0,-4,-2,0,2,4)
=CHOOSE(K2*1,-4,-2,0,2,4)
=CHOOSE(K2/1,-4,-2,0,2,4)
Basically sending the string of a pure number through a math operation has excel convert it to a number. By sending it through a math operation that does not change its value, you get the string as a number.
CHOOSE is like a sequential IF function Supply it with an integer as the first argument and then it will return the value from the subsequent list that matches the number. if the number you supply is greater than the number of options you will get an error.
Alternatively you could just do a straight math convertion on the number stored as a string in K2 using the following formula:
=(K2-3)*2
And as my final option, you could build a table and use VLOOKUP or INDEX/MATCH.
NOTE: If B2:B6 was stored as strings instead of numbers, K2 instead of --K2 would need to be used.

Removing items in a set

I have a function that takes a set, prints the min/max, and then asks the user to remove items in the set until the set is empty.
My code:
def deleteFromNumSet(numsSet):
while len(numsSet)!=0:
print("Max is",max(numsSet),"and Min is", min(numsSet))
num=input("Enter a number between the two.")
if num in numsSet:
print("The number is in the set.")
numsSet.remove(num)
else:
print("The number is not in the set.")
return("No more numbers left in the set.")
The code will say that the "number is not in the set", regardless of whether or not it actually is in the set. It worked using the emulator on repl.it (which was where I coded it originally), but it does not work on my Python program (I am currently using version 3.4.1). I would like to know why it worked on the (older) version of python but does not work now, and a solution that would work for current versions of python.
input() returns a string, not an integer. If our set contains integers then Python will not consider the string equal to the numbers.
Convert the input to an integer first:
num = int(input("Enter a number between the two."))
In Python 2.7, input() is a different function; it essentially does the same as eval(input()) would do in Python 3. As such it automatically interprets digits as a Python integer literal.
To make your code work in both Python 2 and 3 would require a lot more experience with both versions. See the Porting Python 2 Code to Python 3 how-to if you really want to go this way.

Scientific Notation with PrecisionEvaluate in Coldfusion

I have problems working with large numbers and long decimal numbers,
as others have mentioned or solved such issue using PrecisionEvaluate,
I could not get consistent result with such function.
Example with this code :
<cfset n = 0.000000000009>
<cfoutput>#precisionEvaluate(n)#</cfoutput> // this will produce "9E-12"
<cfoutput>#precisionEvaluate("n")#</cfoutput> // this will produce "0.000000000009"
According to Adobe Documentation, using Quote is not recommended (due to processing inefficiency) as well as it should produce same result, however this is not the case from the above code.
Further trials with inconsistent result:
<cfset n = 0.000000000009>
<cfset r = 12567.8903>
<cfoutput>#precisionEvaluate(r * n)#</cfoutput> // this will produce "1.131110127E-7"
<cfoutput>#precisionEvaluate("r * n")#</cfoutput> // this will produce "1.131110127E-7", same as above
<cfoutput>#precisionEvaluate(r / n)#</cfoutput> // this will produce "1396432255555555.55555555555555555556"
<cfoutput>#precisionEvaluate("r / n")#</cfoutput> // this will produce "1396432255555555.55555555555555555556", same as above
Has anybody run into problems with a similar case? What is a practical solution to address the inconsistency?
I have tried : using val() function does not resolve as it is limited to short numbers only,
using numberFormat() function which is difficult as we have to pass number of decimals to format it properly.
When it comes to numbers, do not always believe what you see on the screen. That is just a "human friendly" representation of the number. In your case, the actual results (or numbers) are consistent. It is just a matter of how those numbers are presented ..
PrecisionEvaluate returns a java.math.BigDecimal object. In order to display the number represented by that object inside <cfoutput>, CF invokes the object's toString() method. Per the API, toString() may use scientific notation to represent the value. That explains why it is used for some of your values, but not others. (Though with or without the exponent, it still represents the same number). However, if you prefer to exclude the exponent, just use BigDecimal.toPlainString() instead:
toPlainString() - Returns a string representation of this BigDecimal without an exponent
field....
Example:
<cfscript>
n = 0.000000000009;
r = 12567.8903;
result = precisionEvaluate(r * n);
WriteOutput( result.getClass().name );
WriteOutput("<br />result.toString() ="& result.toString());
WriteOutput("<br />result.toPlainString() ="& result.toPlainString());
</cfscript>
Result:
java.math.BigDecimal
result.toString() =1.131110127E-7
result.toPlainString() =0.0000001131110127

Incorrect conversion when decimal point embedded in VT_BSTR and German locale used

I have a piece of code(c++) that is writing some floating point values to excel like this:
...
values[ position ].bstrVal = formattedValue;
values[ position ].vt = VT_BSTR;
...
as you can see those floating point values are stored in the form of string and the decimal point is formatted in different ways, for example:
"110.000000", "20.11" etc. (this example is for English locale)
Now it works perfectly when English locale is used. However when I switch to German locale in the Control Panel the decimal point is changed to "," (and that's fine) but after passing those localized strings to Excel they are not correctly converted. For example in case of writing "110,000000" I'm getting 100 millions in excel. Other values like "20,11" stay as a text.
The only way to fix this is to overwrite the decimal point with "." in my program before writing to Excel. Any ideas why the conversion is not locale-aware when using VT_BSTR?
I should also add that I tried to switch the locale in my program from default one to German - still no luck.
Thank you in advance
It is never a good idea to let Excel guess at the value type. Do not use VT_BSTR, a currency value should be of variant type VT_CY. Assign the cyVal member with the value. It is an 8 byte integer value (int64 member of type LONGLONG), the currency amount multiplied by 10,000. Ten thousand :)