- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
REAL RPM1, RPM2
CHARACTER(10) sRPM
! e.g., 100.234 to 100.24
RPM1 = CEILING(RPM1*100.0)/100.0
WRITE(sRPM, '(F6.2)', IOSTAT = iErr) RPM1
READ(sRPM, '(F6.2)', IOSTAT = iErr) RPM2
For a win32 app, will the internal representation of RPM1 always equal the internal representation of RPM2? In other words, willRPM1 and RPM2 have exactly the same 32 bit representation in memory?
The reason: I would like to performcalcs using RPM1 and write sRPM to a disc file. At some future time open the app again, read sRPM from a disc file,perform calcs, and get exact answer without any chance of real number round off in memory.
Thanks for any info.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Since a REAL*4 variable can store four 8-bit bytes, this corresponds to 4 characters, so you could also save the bit-pattern as a 4-character variable I think.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the replies, but do not understand how F6.2 impacts on value in memory. I assumed thatusing two different methods to get RPM1 and RPM2, CEILING() vs an internal read(), would be the major contributor to small differences in memoryinary representation.
RPM1 = 100.24
sRPM = '100.24 '
RPM2 = 100.24
Also looked at Z8.8 format and that appears good for transferring INTEGERs, but not sure how that applies to real numbers RPM1 and RPM2.
If I use RPM2from the interal read()andwrite sRPM to disc file at same time, then at some future date start the app and read sRPM from discinto RPM2 then, hopefully, calculated values should be indentical for the 1st and 2nd runs of the app. Is this correct, or amI missing something?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The problem you will encounter is several decimal fractions e.g. 0.1 is a repeating binary fraction that cannot be exactly represented. If your RPMs are always carried to two places then consider computing and storing the numbers as centaRPMs with no fraction.
Or, any time you CEILING the RPM to fix the precision perform your save to file:
RPM1 = CEILING(RPM1*100.0)
WRITE(sRPM, '(F6.0)', IOSTAT=iERR) RPM1
... (LATER)
READ(sRPM, '(F6.0)', IOSTAT=iERR) RPM2
RPM2 = RPM2 / 100.0
In this manner you will not loose precision performing the formatted write and later the formatted read. Your other option would be to write as binary formatted files. But this may introduce portability issues.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Z8.8 works for REALs too - it just stores the 32-bit binary value in hexadecimal.
As Jim says, many decimal fractions cannot be exactly represented in binary floating point. In order to get the same binary representation, you need to write and read several more decimal digits than the precision of the datatype.
I suggest reading the series of three articles "The Perils of Real Numbers" in the Newsletter thread.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Starting to understand:
1) RPM1 may or may not be represented exactly in memory
2) if RPM1 is not exactly represented, then the F6.2 format will round updown
3) RPM2 abtained from the internal read() also may or may not be represented exactly in memory
4) so RPM1 may or may not = RPM2
So,to obtain sameresults for different rumssessions of program:
1) RPM1 = CEILING(.........
2) write(sRPM....) RPM1
3) read(sRPM....) RPM1 and use for current calcs
4) write() sRPM to disc file during current session
3)nextsessionread sRPMfrom disc into RPM1 and calcs should be resonably the same, hopefully with the same7 significant digits
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The point of your write is to provide a snapshot of the calculations. Presumably such that should an abnormal termination occur (due to coding problem innon-critical to solution or power outage, of disk full, etc...) that you then have an opportunity to correct the problem and then resume the calculations (as if the problem did not occur).
I am making an assumption for the following
If your code is designed to periodically coerce the data to a given precision by way of something like
RPM1 = CEILING(RPM1*100.0)/100.0
And if at that point you also decide to checkpoint the data
RPM1 = CEILING(RPM1*100.0)/100.0
WRITE(....) RPM1
And then later, if necessary due toabnormal endof program, read back the data to resume calculation.
Then your resumption will not alway be precisely the same. This is due to the "/100.0" on the CEILING statment potentially producing repeating, and truncated, binary fractions that when written to a file using F6.2 (or whatever) may experience an additional truncation. Then upon a resumption, resuming with a slightly different value.
The more accurate route would be to perform the snapshot when the data is known to be recordable and restorable to the precision desired.
In this case, if you perform the snapshot between the CEILING(RPM1*100.0) and the "/100.0" the data written and the data read will convey the exact same binary data.
An alternate way is to record the data in binary format.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page