I have a variable in Python containing a floating point number (e.g. num = 24654.123
), and I'd like to determine the number's precision and scale values (in the Oracle sense), so 123.45678 should give me (8,5), 12.76 should give me (4,2), etc.
I was first thinking about using the string representation (via str
or repr
), but those fail for large numbers (although I understand now it's the limitations of floating point representation that's the issue here):
>>> num = 1234567890.0987654321
>>> str(num) = 1234567890.1
>>> repr(num) = 1234567890.0987654
Edit:
Good points below. I should clarify. The number is already a float and is being pushed to a database via cx_Oracle. I'm trying to do the best I can in Python to handle floats that are too large for the corresponding database type short of executing the INSERT and handling Oracle errors (because I want to deal with the numbers a field, not a record, at a time). I guess map(len, repr(num).split('.'))
is the closest I'll get to the precision and scale of the float?
(0) Please confirm or deny: You are given floats to use, this is unavoidable, you can't get your data as decimal, the Oracle datatypes include decimal-based types, and this fundamental mismatch is unavoidable. Please explain any full or partial denial.
(1) Your "fail for large numbers" remark is misleading/irrelevant/wrong -- you say that your starting point is a float, but 1234567890.0987654321 can't be represented as a float, as shown by the result of repr().
(2) Perhaps you could use the NEW repr (Python 2.7 and 3.1) which provides the minimum possible precision of repr(x) that still satisfies
float(repr(x)) == x
E.g. old repr(1.1) produces "1.1000000000000001", new repr(1.1) produces "1.1"
About "I guess map(len, repr(num).split('.')) is the closest I'll get to the precision and scale of the float?": You need a strategy to handle (a) negative and zero numbers (b) numbers like
1.1e20
Digging in Objects/floatobject.c should turn up the C code for the new repr() of a float object, should you need to use Python 2.6 or earlier.
(3) Perhaps if you told us the specs for the relevant Oracle data types, we could help you devise checks for choosing which type can contain a given float value.