Re: [Seed7-users] Seed7 Compilation Errors
Interpreter and compiler for the Seed7 programming language.
Brought to you by:
thomas_mertes
From: Thomas M. <tho...@gm...> - 2021-03-21 08:31:26
|
Hi Zachary, Many thanks for your testing and your description of the chkflt.sd7 problems. You wrote: > Hey Thomas, > > It seems I'm still getting this error in version 2021-02-23. I've attached > all the relevant files again. > > I'm not sure what the issue is, but I had a look in the file "chkflt.sd7", > and the lines 4495 and 4496 don't make sense to me. If I understand > correctly, it means if truncating "9223372036854775297.0" does not raise a > range error (which it wouldn't, on my system) and truncating > "9223372036854775297.0" does not equal "9223372036854775807", then an error > is raised. However, I fail to see why truncating "9223372036854775297.0" > would ever equal the higher number of "9223372036854775807". As--on my > system with the higher number of "9223372036854775807"--wouldn't truncating > "9223372036854775297.0" equal itself and not the higher number? The problem is that the tests for trunc() and round() in "chkflt.sd7" test two things instead of one: 1. How a float literal is mapped to the IEEE 754 double-precision float. 2. How trunc() respectively round() work. The IEEE 754 double-precision floating-point format cannot represent all numbers used in these tests. The actual numbers that can be represented as IEEE 754 double-precision float are: 9223372036854773760.0 this is: float(bin64(16#43dffffffffffffe)) 9223372036854774784.0 this is: float(bin64(16#43dfffffffffffff)) 9223372036854775808.0 this is: float(bin64(16#43e0000000000000)) 9223372036854777856.0 this is: float(bin64(16#43e0000000000001)) The numbers in between them (such as 9223372036854775297.0) do not exist as IEEE 754 double-precision float. So a literal between these numbers is rounded towards the next existing double-precision float. Tests for trunc() and round() with these in-between numbers depend on how float literals are rounded. These literal rounding is a totally different issue that should not be considered when testing trunc() and round(). I decided to reduce the tests to: trunc( 9223372036854773760.0) <> 9223372036854773760 or trunc( 9223372036854774784.0) <> 9223372036854774784 or not raisesRangeError(trunc( 9223372036854775807.0)) and trunc( 9223372036854775807.0) <> 9223372036854775807 or not raisesRangeError(trunc( 9223372036854777856.0)) or Now only representable IEEE 754 double-precision floating-point values are used. The only thing left is the use of 9223372036854775807.0 instead of 9223372036854775808.0. In this case I am quite sure that the rounding of the float literal chooses 9223372036854775808.0 as IEEE 754 double-precision representation. On your computer the float literal 9223372036854775807.0 is internally represented as 9223372036854775808.0 and trunc() converts it to 9223372036854775807. The test for 9223372036854775807.0 either expects a RANGE_ERROR or the correct value (9223372036854775807). Seed7 uses the C cast functionality to trunc() and round() float values to integers. The C cast is used for performance reasons, because C probably uses a fast solution for the cast. Unfortunately the C cast of a float to an integer does not always work the same. Some C compilers do cast 9223372036854775808.0 to 9223372036854775807 and others return a negative value (-9223372036854775808). Therefore I decided that the Seed7 functions trunc() and round() either return the correct value or raises RANGE_ERROR. The next release will contain the fixed chkflt.sd7. If there are still issues please tell me. Regards Thomas |