[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[microblaze-uclinux] Error with double to unsigned integer cast



What I do:
I'm using EDK 8.1 and uClinux (downloaded from CVS at 24.04.2006)
I calculate an unsigned integer with double precission.
I calculate a signed integer with double precission.
What I see:
When the result should be 0x6FD91D85 I get 0x0 as a result, but good results when it's two MSB bits are not "01". When I change the signed integer calculation into something without double precission, the result of the unsigned integer calculation is also good for the mysterious 0x6FD91D85.

What I also checked:
When I run the program on my PC's Linux and not on MB's uClinux everything is fine. When I put the same set of formulas into a standalone application on MB, there's also no error.
So I guess it's a problem in one of the libraries.

I hope that I provided enough information for the experts to fix this problem.



In the attachment I put a small programm that demonstrates the error as shown in the log below and a small change in the programm so that the error doesn't show up. As well as a very simple design that has the same calculations as a standalone application.


If you want to try it yourself. Add the testcastbad and testcastgood to your uClinux user directory and make a link testdbl on either one of the two directories. Add testdbl to your uClinux and compile it.

Have a look at the output for the bad and the good case:
===========================================================
ln -s testcastbad testdbl
===========================================================


uclinux-auto login: root
Password:
# testdbl
Intention: Let's demonstrate a conversion error from double to integer
that occurs in our formula: Now we show the bad version.
Unluckily we calculate some signed values too.
testdbl Version: Formula - unsigned int
unsigned integer_value = ((double) board_clock_reg) * dx/dy;
signed integer_value = ((double) board_clock_reg) * dv/dw;

Do you want to calc your own? (Y/n)?

Please Enter two unsigned for the formula: dx dy (both integers: dx/dy ~= 1/1 ): 1 1

Please Enter two signed for the formula: dv dw (both integers: dv/dw ~= 1/1 ): 1 1
The double result of a formula 0 is  : 1876499845.000000
The integer cast of the above is     : 0
The directly casted integer result is: 0
The disturbing formula's result is   : 0
Check for different results like 2^33,2^32, 2^32-1, 2^31-1, 2^30-1

Do you want to continue? (Y/n)?

Please Enter two unsigned for the formula: dx dy (both integers: dx/dy ~= 1/1 ): 1 2

Please Enter two signed for the formula: dv dw (both integers: dv/dw ~= 1/1 ): 1 2
The double result of a formula 0 is  : 938249922.500000
The integer cast of the above is     : 938249922
The directly casted integer result is: 938249922
The disturbing formula's result is   : 938249922
Check for different results like 2^33,2^32, 2^32-1, 2^31-1, 2^30-1

Do you want to continue? (Y/n)? Jan 1 00:01:04 dhcpcd[33]: timed out waiting for a valid DHCP se



Please Enter two unsigned for the formula: dx dy (both integers: dx/dy ~= 1/1 ): 2 1

Please Enter two signed for the formula: dv dw (both integers: dv/dw ~= 1/1 ): 2 1
The double result of a formula 0 is  : 3752999690.000000
The integer cast of the above is     : 2147483648
The directly casted integer result is: 2147483648
The disturbing formula's result is   : 2147483647
Check for different results like 2^33,2^32, 2^32-1, 2^31-1, 2^30-1

Do you want to continue? (Y/n)?

Please Enter two unsigned for the formula: dx dy (both integers: dx/dy ~= 1/1 ): 3 2

Please Enter two signed for the formula: dv dw (both integers: dv/dw ~= 1/1 ): 3 2
The double result of a formula 0 is  : 2814749767.500000
The integer cast of the above is     : 2814749767
The directly casted integer result is: 2814749767
The disturbing formula's result is   : 2147483647
Check for different results like 2^33,2^32, 2^32-1, 2^31-1, 2^30-1

Do you want to continue? (Y/n)?

Please Enter two unsigned for the formula: dx dy (both integers: dx/dy ~= 1/1 ): 1 1

Please Enter two signed for the formula: dv dw (both integers: dv/dw ~= 1/1 ): 1 1
The double result of a formula 0 is  : 1876499845.000000
The integer cast of the above is     : 0
The directly casted integer result is: 0
The disturbing formula's result is   : 0
Check for different results like 2^33,2^32, 2^32-1, 2^31-1, 2^30-1

Do you want to continue? (Y/n)? n

Thank you!

#

===========================================================
ln -s testcastgood testdbl
===========================================================
uclinux-auto login: root
Password:
# testdbl
Intention: Let's demonstrate a conversion error from double to integer
that occurs in our formula: Now we show the good version.
Luckily we calculate some signed values too, but not with double precission.
testdbl Version: Formula - unsigned int
unsigned integer_value = ((double) board_clock_reg) * dx/dy;
signed integer_value = dv/dw;

Do you want to calc your own? (Y/n)?

Please Enter two unsigned for the formula: dx dy (both integers: dx/dy ~= 1/1 ): 1 1

Please Enter two signed for the formula: dv dw (both integers: dv/dw ~= 1/1 ): 1 1
The double result of a formula 0 is  : 1876499845.000000
The integer cast of the above is     : 1876499845
The directly casted integer result is: 1876499845
The non-disturbing formula's result is : 1
Check for different results like 2^33,2^32, 2^32-1, 2^31-1, 2^30-1

Do you want to continue? (Y/n)?




This is the configuration options of my MicroBlaze
===========================================================

BEGIN microblaze
 PARAMETER INSTANCE = microblaze_0
 PARAMETER HW_VER = 4.00.a
 PARAMETER C_USE_FPU = 1
 PARAMETER C_USE_DIV = 1
 PARAMETER C_USE_BARREL = 1
 PARAMETER C_DEBUG_ENABLED = 1
 PARAMETER C_NUMBER_OF_PC_BRK = 2
 PARAMETER C_USE_ICACHE = 1
# 2048 uses 2 BRAMs, 4096 uses 4 BRAMs
 PARAMETER C_CACHE_BYTE_SIZE = 2048
 PARAMETER C_USE_DCACHE = 1
# 2048, 4096, 8192 always uses 5 BRAMs.
 PARAMETER C_DCACHE_BYTE_SIZE = 8192
 PARAMETER C_ICACHE_USE_FSL = 1
 PARAMETER C_DCACHE_USE_FSL = 1
 PARAMETER C_ICACHE_BASEADDR = 0xE0000000
 PARAMETER C_ICACHE_HIGHADDR = 0xE0ffffff
 PARAMETER C_DCACHE_BASEADDR = 0xE0000000
 PARAMETER C_DCACHE_HIGHADDR = 0xE0ffffff
 BUS_INTERFACE DLMB = d_lmb
 BUS_INTERFACE ILMB = i_lmb
 BUS_INTERFACE DOPB = d_opb
 BUS_INTERFACE IOPB = d_opb
 BUS_INTERFACE IXCL = ixcl
 BUS_INTERFACE DXCL = dxcl
 PORT CLK = sys_clk
 PORT DBG_CAPTURE = DBG_CAPTURE_s
 PORT DBG_CLK = DBG_CLK_s
 PORT DBG_REG_EN = DBG_REG_EN_s
 PORT DBG_TDI = DBG_TDI_s
 PORT DBG_TDO = DBG_TDO_s
 PORT DBG_UPDATE = DBG_UPDATE_s
 PORT Interrupt = microblaze_0_interrupt
END



--
Andreas Roland
Murwiesenstr. 47
8057 Zürich
Switzerland
Tel: +41-1-313 12 16
Mobile: +41-78 656 0 323
Email: arol'#'wolke7.net

Attachment: double_trouble.tar.gz
Description: GNU Zip compressed data

Attachment: buggy_81_a0-empty.tar.gz
Description: GNU Zip compressed data