Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Converting real*4 to double

fritschen
初學者
2,970 檢視
Is there an easy way to convert a real*4 number to real*8 with the "appended fraction" equal to 0?

Example:
If you code
real(4) :: a
real(8) :: b
a = 125.0
b = dble(a)
then
b = 125.00000762....
or something else.
I want: b = 125.0000000000

Thanks
Ralf
0 積分
12 回應
Steven_L_Intel1
2,970 檢視
The fraction is equal to 0 - binary 0! What you really want is to use 125.0D0 as the constant, which is double-precision. 125.0 is single-precision.

Steve
durisinm
新手
2,970 檢視
Couldn't you also use 125._8 and get the same result?

Mike
Steven_L_Intel1
2,970 檢視
You can, yes. But the choice of _8 is implementation-dependent. You could define a PARAMETER constant using SELECTED_REAL_KIND, and a lot of people do it that way, but using D0 works everywhere and is easy to describe. The new way isn't always better!

Steve
fritschen
初學者
2,970 檢視
Thanks for your replies but I posted the few lines of code only to give an example. In real live I have a lot of code and have to use the variable "a" most of the time as real*4. Only some calculations have to be done in *8. I can't set b to 125d0 but want to have b = a with the fraction (in this case after the 5th digit) to be equal to 00000.
Ralf
wkramer
初學者
2,970 檢視
The only way I can think of is using an internal write and read. Write the real*4 to a character string and read the real*8 from the character string.
I have tried this method once, but it slowed down the program considerably. I now stick to real*8 only if possible.

Walter Kramer
david_jones
初學者
2,970 檢視
One way of acheiving this would be to:
(i) multiply by however many thousand it needs;
(ii) convert to integer;
(iii) then convert to double precision;
(iv) finally divide by however many thousand.

You might need to use the new 8-byte integers.

David Jones
durisinm
新手
2,970 檢視
What would be the appropriate way to do the reverse kind of conversion: converting a double precision number to single precision? Should people use the REAL, FLOAT, or SNGL function?

Is the SNGL function a part of standard Fortran? The Compaq documentation sometimes lists it in black print and sometimes in blue print.

Mike
Steven_L_Intel1
2,970 檢視
SNGL is standard.

Steve
NH_Veldhuijzen
初學者
2,970 檢視
Hi,

I often want to do this. My simple solution, which never failed so far, is to set variable b to zero before assigning a to it. I got the output:

1.2500000000E+02
405F400000000000

from this simple program:

program from4to8
real(4) :: a
real(8) :: b
a = 125.0
b=0.d0
b = dble(a)
write (*,'(es16.10/z16)') b,b
end program from4to8

I hope this helps. - Niels -
NH_Veldhuijzen
初學者
2,970 檢視
After my first reply, I realized this is a serious problem. Programmers should trust that their compilers don't insert unwanted bits into numbers. But... then I saw that it isn't necessarily the compiler that is at fault. For I could not replicate Ralf's results (CVF 6.6A). I tried several statements, even looking at b before it has been assigned a value by me:

program from4to8
real(4) :: a
real(8) :: b
a = 125.0
write (*,'(es16.10,tr4,z16)') b,b ! Not initialised by me
b=a ! Ralf's statements
write (*,*) b
write (*,'(es16.10,tr4,z16)') b,b
b=0.d0
write (*,'(es16.10,tr4,z16)') b,b
b = dble(a)
write (*,'(es16.10,tr4,z16)') b,b
end program from4to8

This is what I got:

0.0000000000E+00 0
125.000000000000
1.2500000000E+02 405F400000000000
0.0000000000E+00 0
1.2500000000E+02 405F400000000000

So, I don't know where Ralf's spurious bit come from. Maybe some obscure option has been cleared inadvertently?
Puzzling. - Niels -
tlillys
初學者
2,970 檢視
I am encountering a similar problem with 6.6B.

In the following code, the explicit conversion of a real to double for a subtraction is causing some serious problems. And it also appears to be inconsistent. The two cases posed to the subroutine should result in the same difference but they don't and hence the logic path is different.

Any clues as to why?
Steven_L_Intel1
2,970 檢視
I suggest reading the series "The Perils of Real Numbers" in the CVF Newsletter On the X86 architecture, funny things can happen as intermediate expressions move in and out of registers during optimized code. The optimized results are better, but can be inconsistent. There is an "Enable Floating Point Consistency" option which sometimes improves things (and slows down the code).

In your case, tillys, you really need to read the articles - the values you have can't be represented exactly in binary floating point, and while the differences might seem to be the same when done in decimal, they aren't in fixed-precision binary float.

Steve
回覆