How many digits including after decimal point can NUMBER(x) hold? - plsql

For plsql data type NUMBER(x) is want to know the maximum number of digits after the decimal place it can hold (assuming i am using only 1 digit before decimal point) . Is there some rule by which this can be derived .

According to Oracle's documentation:
NUMBER
999...(38 9's) x10125 maximum value
-999...(38 9's) x10125 minimum value
Can be represented to full 38-digit precision (the mantissa).
Simply said, you have 38 significant (decimal) digits.
Given your case, if you use 1 digit before the decimal point, you still have 37 digits available at max just after the decimal point:
NUMBER(38,37)
This will cover the range:
-9.9999999999999999999999999999999999999
+9.9999999999999999999999999999999999999
With an ULP of:
0.0000000000000000000000000000000000001
This is better in term of precision than IEEE754 floating point numbers and you will have exact representation of decimal numbers.
As a side-note, few things to know:
NUMBER(x) is the same thing as NUMBER(x,0). That is a signed decimal integer.
PL/SQL will silently discard numbers after the decimal separator when doing an affectation to a number with a scale lower than the original. see this example:
declare
n1 number(12,1);
n2 number(11);
begin
n1 := 12345678901.2;
dbms_output.put_line(n1);
n2 := n1; -- loose precision here !!!
n1 := n2;
dbms_output.put_line(n1);
dbms_output.put_line(n2);
end;
Displaying 12345678901.2, and then 12345678901 and 12345678901
The CAST operator will behave exactly same manner:
select CAST(12345678901.2 AS NUMBER(11)) FROM DUAL;
resulting in 12345678901.

Related

Representing decimal numbers in binary

How do I represent integers numbers, for example, 23647 in two bytes, where one byte contains the last two digits (47) and the other contains the rest of the digits(236)?
There are several ways do to this.
One way is to try to use Binary Coded Decimal (BCD). This codes decimal digits, rather than the number as a whole into binary. The packed form puts two decimal digits into a byte. However, your example value 23647 has five decimal digits and will not fit into two bytes in BCD. This method will fit values up to 9999.
Another way is to put each of your two parts in binary and place each part into a byte. You can do integer division by 100 to get the upper part, so in Python you could use
upperbyte = 23647 // 100
Then the lower part can be gotten by the modulus operation:
lowerbyte = 23647 % 100
Python will directly convert the results into binary and store them that way. You can do all this in one step in Python and many other languages:
upperbyte, lowerbyte = divmod(23647, 100)
You are guaranteed that the lowerbyte value fits, but if the given value is too large the upperbyte value many not actually fit into a byte. All this assumes that the value is positive, since negative values would complicate things.
(This following answer was for a previous version of the question, which was to fit a floating-point number like 36.47 into two bytes, one byte for the integer part and another byte for the fractional part.)
One way to do that is to "shift" the number so you consider those two bytes to be a single integer.
Take your value (36.47), multiply it by 256 (the number of values that fit into one byte), round it to the nearest integer, convert that to binary. The bottom 8 bits of that value are the "decimal numbers" and the next 8 bits are the "integer value." If there are any other bits still remaining, your number was too large and there is an overflow condition.
This assumes you want to handle only non-negative values. Handling negatives complicates things somewhat. The final result is only an approximation to your starting value, but that is the best you can do.
Doing those calculations on 36.47 gives the binary integer
10010001111000
So the "decimal byte" is 01111000 and the "integer byte" is 100100 or 00100100 when filled out to 8 bits. This represents the float number 36.46875 exactly and your desired value 36.47 approximately.

How to convert decimal to binary?

How to convert the decimal number "18.25" to binary? I've been confused by the decimal points .25.
Just like you divide this 18 by 2 repeatedly to form a decimal representation for it, you need to do the reverse to convert the decimal part of the number to binary. You need to multiply that decimal portion of the number by 2 repeatedly until it gives a standalone digit. The result(product) of the first multiplication will be the input to the second multiplication and this continues until we reach a stagnant steady integer value.
So, in your case, the 18.25's decimal part is 0.25.
Let's begin by multiplying it with 2.
0.25*2=0.5 // 0
0.5*2=1.0 // 1
Hunt finishes as we end up with the product coming as a standalone integer.
Also, the decimal to binary conversion of 18 is (10010)base 2. This you can easily calculate as you know it,mentioned in the question.
Hence, the decimal representation for 18.25 will be (10010.01)base 2---see,serially 01 in the order unlike the numbers where we traverse from bottom to top!
I hope it is clear.
with recursiveCTE(num) as (
select &EnterNum num from dual
union all
select trunc(num/2) from recursiveCTE
where trunc(num/2)> 0
),
ref as (SELECT num, mod(num, 2) bin_remainder from recursiveCTE)
select reverse(to_char(replace(wm_concat(bin_remainder), ','))) binary_num from ref;

Can a IEEE 754 real number "cover" all integers within its range?

The original question was edited (shortened) to focus on a problem of precision, not range.
Single, or double precision, every representation of real number is limited to (-range,+range). Within this range lie some integer numbers (1, 2, 3, 4..., and so on; the same goes with negative numbers).
Is there a guarantee that a IEEE 754 real number (float, double, etc) can "cover" all integers within its range? By "cover" I mean the real number will represent the integer number exactly, not as (for example) "5.000001".
Just as reminder: http://www3.ntu.edu.sg/home/ehchua/programming/java/DataRepresentation.html nice explanation of various number representation formats.
Update:
Because the question is for "can" I am also looking for the fact this cannot be done -- for it quoting a number is enough. For example "no it cannot be done, for example number 1748574 is not represented exactly by float number" (this number is taken out of thin air of course).
For curious reader
If you would like to play with IEEE 754 representation -- on-line calculator: http://www.ajdesigner.com/fl_ieee_754_word/ieee_32_bit_word.php
No, not all, but there exists a range within which you can represent all integers accurately.
Structure of 32bit floating point numbers
The 32bit floating point type uses
1 bit for the sign
8 bits for the exponent
23 bits for the fraction (leading 1 implied)
Representing numbers
Basically, you have a number in the form
(-)1.xxxx_xxxx_xxxx_xxxx_xxxx_xxx (binary)
which you then shift left/right with the (unbiased) exponent.
To have it represent an integer requiring n bits, you need to shift it by n-1 bits to the left. (All xes beyond the floating point are simply zero)
Representing integers with 24 bits
It is easy to see, that we can represent all integers requiring 24 bits (and less)
1xxx_xxxx_xxxx_xxxx_xxxx_xxxx.0 (unbiased exponent = 23)
since we can set the xes at will to either 1 or 0.
The highest number we can represent in this fashion is:
1111_1111_1111_1111_1111_1111.0
or 2^24 - 1 = 16777215
The next higher integer is 1_0000_0000_0000_0000_0000_0000. Thus, we need 25 bits.
Representing integers with 25 bits
If you try to represent a 25 bit integer (unbiased exponent = 24), the numbers have the following form:
1_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0.0
The twenty-three digits that are available to you have all been shifted past the floating point. The leading digit is always a 1. In total, we have 24 digits. But since we need 25, a zero is appended.
A maximum is found
We can represent ``1_0000_0000_0000_0000_0000_0000with the form1_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0.0, by simply assigning 1to allxes. The next higher integer from that is: 1_0000_0000_0000_0000_0000_0001. It's easy to see that this number cannot be represented accurately, because the form does not allow us to set the last digit to 1: It is always 0`.
It follows, that the 1 followed by 24 zeroes is an upper bound for the integers we can accurately represent.
The lower bound simply has its sign bit flipped.
Range within which all integers can be represented (including boundaries)
224 as an upper bound
-224 as a lower bound
Structure of 64bit floating point numbers
1 bit for the sign
11 exponent bits
52 fraction bits
Range within which all integers can be represented (including boundaries)
253 as an upper bound
-253 as a lower bound
This easily follows by applying the same argumentation to the structure of 64bit floating point numbers.
Note: That is not to say these are all integers we can represent, but it gives you a range within which you can represent all integers. Beyond that range, we can only represent a power of two multiplied with an integer from said range.
Combinatorial argument
Simply convincing ourselves that it is impossible for 32bit floating point numbers to represent all integers a 32bit integer can represent, we need not even look at the structure of floating point numbers.
With 32 bits, there are 232 different things we can represent. No more, no less.
A 32bit integer uses all of these "things" to represent numbers (pairwise different).
A 32bit floating point number can represent at least one number with a fractional part.
Thus, it is impossible for the 32bit floating point number to be able to represent this fractional number in addition to all 232 integers.
macias, to add to the already excellent answer by phant0m (upvoted; I suggest you accept it), I'll use your own words.
"No it cannot be done, for example number 16777217 is not represented exactly by float number."
Also, "for example number 9223372036854775809 is not represented exactly by double number".
This is assuming your computer is using the IEEE floating point format, which is a pretty strong bet.
No.
For example, on my system, the type float can represent values up to approximately 3.40282e+38. As an integer, that would be approximately 340282000000000000000000000000000000000, or about 2128.
The size of float is 32 bits, so it can exactly represent at most 232 distinct numbers.
An integer object generally uses all of its bits to represent values (with 1 bit dedicated as a sign bit for signed types). A floating-point object uses some of its bits to represent an exponent (8 bits for IEEE 32-bit float); this increases its range at the cost of losing precision.
A concrete example (1267650600228229401496703205376.0 is 2100, and is exactly representable as a float):
#include <stdio.h>
#include <float.h>
#include <math.h>
int main(void) {
float x = 1267650600228229401496703205376.0;
float y = nextafterf(x, FLT_MAX);
printf("x = %.1f\n", x);
printf("y = %.1f\n", y);
return 0;
}
The output on my system is:
x = 1267650600228229401496703205376.0
y = 1267650751343956853325350043648.0
Another way to look at it:
A 32-bit object can represent at most 232 distinct values.
A 32-bit signed integer can represent all integer values in the range -2147483648 .. 2147483647 (-231 .. +231-1).
A 32-bit float can represent many values that a 32-bit signed integer can't, either because they're fractional (0.5) or because they're too big (2.0100). Since there are values that can be represented by a 32-bit float but not by a 32-bit int, there must be other values that can be represented by a 32-bit int but not by a 32-bit float. Those values are integers that have more significant digits than a float can handle, because the int has 31 value bits but the float has only about 24.
Apparently you are asking whether a Real data type can represent all of the integer values in its range (absolute values up to FLT_MAX or DBL_MAX, in C, or similar constants in other languages).
The largest numbers representable by floating point numbers stored in K bits typically are much larger than the 2^K number of integers that K bits can represent, so typically the answer is no. 32-bit C floats exceed 10^37, 32-bit C integers are less than 10^10. To find out the next representable number after some number, use nextafter() or nextafterf(). For example, the code
printf ("%20.4f %20.4f\n", nextafterf(1e5,1e9), nextafterf(1e6,1e9));
printf ("%20.4f %20.4f\n", nextafterf(1e7,1e9), nextafterf(1e8,1e9));
prints out
100000.0078 1000000.0625
10000001.0000 100000008.0000
You might be interested in whether an integer J that is between two nearby fractional floating values R and S can be represented exactly, supposing S-R < 1 and R < J < S. Yes, such a J can be represented exactly. Every float value is the ratio of some integer and some power of 2. (Or is the product of some integer and some power of 2.) Let the power of 2 be P, and suppose R = U/P, S = V/P. Now U/P < J < V/P so U < J*P < V. More of J*P's low-order bits are zero than are those of U, V (because V-U < P, due to S-R < 1), so J can be represented exactly.
I haven't filled in all the details to show that J*P-U < P and V-J*P < P, but under the assumption S-R < 1 that's straightforward. Here is an example of R,J,S,P,U,V value computations: Let R=99999.9921875 = 12799999/128, (ie P=128); let S=100000.0078125 = 12800001/128; we have U=0xc34fff and V=0xc35001 and there is a number between them that has more low-order zeroes than either; to wit, J = 0xc35000/128 = 12800000/128 = 100000.0. For the numbers in this example, note that U and V require 24 bits for their exact representations (6 ea. 4-bit hex digits). Note that 24 bits is the number of bits of precision in IEEE 754 single-precision floating point numbers. (See table in wikipedia article.)
That each floating point number is a product or ratio of some integer and some power of 2 (as mentioned two paragraphs above) also is discussed in that floating point article, in a paragraph that begins:
By their nature, all numbers expressed in floating-point format are rational numbers with a terminating expansion in the relevant base (for example, ... a terminating binary expansion in base-2). Irrational numbers, such as π or √2, or non-terminating rational numbers, must be approximated. The number of digits (or bits) of precision also limits the set of rational numbers that can be represented exactly.

What types of numbers are representable in binary floating-point?

I've read a lot about floats, but it's all unnecessarily involved. I think I've got it pretty much understood, but there's just one thing I'd like to know for sure:
I know that, fractions of the form 1/pow(2,n), with n an integer, can be represented exactly in floating point numbers. This means that if I add 1/32 to itself 32 million times, I would get exactly 1,000,000.
What about something like 1/(32+16)? It's one over the sum of two powers of two, does this work? Or is it 1/32+1/16 that works? This is where I'm confused, so if anyone could clarify that for me I would appreciate it.
The rule can be summed up as this:
A number can be represented exactly in binary if the prime factorization of the denominator contains only 2. (i.e. the denominator is a power-of-two)
So 1/(32 + 16) is not representable in binary because it has a factor of 3 in the denominator. But 1/32 + 1/16 = 3/32 is.
That said, there are more restrictions to be representable in a floating-point type. For example, you only have 53 bits of mantissa in an IEEE double so 1/2 + 1/2^500 is not representable.
So you can do sum of powers-of-two as long as the range of the exponents doesn't span more than 53 powers.
To generalize this to other bases:
A number can be exactly represented in base 10 if the prime factorization of the denominator consists of only 2's and 5's.
A rational number X can be exactly represented in base N if the prime factorization of the denominator of X contains only primes found in the factorization of N.
A finite number can be represented in the common IEEE 754 double-precision format if and only if it equals M•2e for some integers M and e such that -253 < M < 253 and -1074 ≤ e ≤ 971.
For single precision, -224 < M < 224 and -149 ≤ e ≤ 104.
For double-precision, these are consequences of the facts that the double-precision format uses 52 bits to store a significand (which normally has 53 bits due to an implicit 1) and uses 11 bits to store an exponent. 11 bits encodes numbers from 0 to 2047, but 0 and 2047 are excluded for special purposes, and the encoded number is biased by 1023, so it represents unbiased exponents from -1022 to 1023. However, these unbiased exponents are for significands in the interval [1, 2), and those significands have fractions. To express the significand as an integer, I adjusted the exponent range by 52. Single-precision is similar, with 23 bits to store a 24-bit significand, 8 bits for the exponent, and a bias of 127.
Expressing the representable numbers using an integer times a power of two rather than the more common fractional significand simplifies some number theory and other reasoning about floating-point properties. I used it in this answer because it allows the set of representable values to be expressed concisely.
Floating-point numbers are literally represented using the form:
1.m * 2^e
Where 1.m is a binary fraction and e is a positive or negative integer.
As such, you can represent 1/32 + 1/16 exactly, as:
1.1000000 * 2^-4
(1.10 being the binary fraction equivalent to 1.5.) 1/48, however, is not representable in this format.
One point not yet mentioned is that semantically, a floating-point number may be best regarded as representing a range of values. The range of values has a very precisely-defined center point, and the IEEE spec generally requires that the result of a floating-point computation be the number whose range contains the point one would get operating upon the center-points of the original numbers, but in the sequence:
double N1 = 0.1;
float N2 = (float)N1;
double N3 = N2;
N2 is the unambiguous correct single-precision representation of the value that had been represented in N1, despite the language's silly requirement to use an explicit cast. N3 will represent one of the values that N2 could represent (the language spec happens to choose the double value whose range is centered upon the middle of the range of the float). Note that while N2 represents the value of its type whose range contains the correct value, N3 does not.
Incidentally, conversion of a number from a string to a float in .net and .net languages seems to go through an intermediate conversion to double, which may sometimes alter the value. For example, even though the value 13571357 is representable as a single-precision float, the value 13571357.499999999069f gets rounded to 13571358 (even though it's obviously closer to 13571357).

Convert decimal to hex/binary

I have small math question.
Is there any way to convert decimal number (for example 3.14) to hex or binary? If it's possible, can anybody place here some links to tutorials or exaplanations? (I don't want it for some language, I need it generally in math.) Please help.
EDIT:
Input passed in code:
0.1
Output in ASM code:
415740h
Another input:
0.058
Another output by compiler:
00415748h
But how has been this done? How can be it converted?
I do not recognize your output samples as encodings of floating-point numbers or other common representations of .1 and .058. I suspect these numbers are addresses where the assembler or compiler has stored the floating-point encoding.
In other words, you wrote some text that including a floating-point literal, and the assembler or compiler converted that literal to a floating-point encoding, stored it at some address, and then put the address into an instruction that loads the floating-point encoding from memory.
This hypothesis is consistent with the fact that the two numbers differ by eight. Since double-precision floating-point is commonly eight bytes, the second address (0x415748) was eight bytes beyond the first address (0x415740).
The process for encoding a number in floating-point is roughly this:
Let x be the number to be encoded.
Set s (a sign bit) to 0 if x is positive and to 1 if x is negative. Set x to the absolute value of x.
Set e (an exponent) to 0. Repeat whichever of the following is appropriate:
If x is 2 or greater, add 1 to e and divide x by 2. Repeat until x is less than 2.
If x is less than 1, add -1 to e and multiply x by 2. Repeat until x is at least 1.
When you are done with the above, x is at least 1 and is less than 2. Also, the original number equals (-1)s·2e·x. That is, we have represented the number with a sign bit (s), and exponent of two (e), and a significand (x) that is in [1, 2) (includes 1, excludes 2).
Set f = (x-1)·252. Round f to the nearest integer (if it is a tie between two integers, round to the even integer). If f is now 252, set f to 0 and add 1 to e. (This step finds the 52 bits of x that are immediately after the “decimal point“ when x is represented as a binary numeral, with rounding after the 52nd digit, and it adjusts the exponent if rounding at that position rounds x up to 2, which is out of interval where we want it.)
Add 1023 to e. This has no numerical significance with regard to x; it is simply part of the floating-point encoding. When decoding, 1023 gets subtracted.
Now, convert s, e, and f to binary numerals, using exactly one digit for s, 11 digits for e, and 52 digits for f. If necessary, including leading zeroes so that e is represented with exactly 11 binary digits and f is represented with exactly 52 binary digits. Concatenate those digits, and you have 64 bits. That is the common IEEE 754 encoding for a double-precision floating-point number.
There are some special cases: If the original number is zero, use zero for s, e, and f. (s can also be 1, to represent a special “negative zero“. If, before adding 1023, e is less than -1022, then some adjustments have to be made to get a “denormal“ result or zero, which I do not describe further at the moment. If, before adding 1023, e is more than 1023, then the magnitude of the number is too large to be represented in floating point. It can be encoded as infinity instead, by setting e (after adding 1023) to 2047 and f to zero.
Decimal to Floating-point:
http://sandbox.mc.edu/~bennet/cs110/flt/dtof.html

Resources