1

I have recently learned about fixed-sized integer and am planning to use them in an old program I wrote years ago.

Is there any equivalent of fixed-sized int for float and/or double?

My plan is to use "native types" int,float,double for the biggest part of the program and only specify fixed-size types when portability is a concern (like read/write with a binary file). I use a binary file store data like: date yyyymmdd (so uint32), flags [0,4] (so uint8), string (null terminated string) and currencies (now it's double).

Concerning portability, the program is "portable" is the sense that it can be compiled (or cross-compiled) and run on different platform. So far: linux, windows, android (natively, through a terminal emulator without GUI) and OpenBSD (strcat/strcpy only needs to be replaced by strlcat/strlcpy in 2 lines). I am concerned about what could happen to the stored float/double if I used the same binary data file between linux x86_64, android arm-something, windows 32 something, etc... I would like to have a way to enforce a unique size and representation of floating-point values in the binary file.

asked Oct 14, 2016 at 14:43
6
  • If __STDC_IEC_559__ is defined, then yes, else no. Need more details on your FP portability requirements. Loosely: recommend store currencies as a string. Commented Oct 14, 2016 at 15:01
  • The IEEE standard for floating point is ubiquitous today, except in some very cheap embedded processors. Since you are reading a file you can ignore them. What you can't completely ignore is byte-order (aka endiness), that's a problem with your fixed-size integers as well. Commented Oct 14, 2016 at 15:25
  • @chux: Post edited for clarity about portability. Commented Oct 15, 2016 at 11:32
  • @Hans Passant: I never though about endiness. I am considering storing data in a plain text file now... Commented Oct 15, 2016 at 11:34
  • Would my answer to a related question help? Commented Oct 15, 2016 at 11:47

2 Answers 2

1

For currencies, suggests special handling. Select a fixed width integer type to meet range needs (int64_t or int32_t) and scale by smallest monetary unit. If code is only storing/reading values like 123.12

void Store_int32(int32_t x); // Handles int32_t in endian independent method
int32_t Get_int32(void); // Handles int32_t in endian independent method
void Store_Currency(double c) {
 if (c < INT32_MIN/100.0 || c > INT32_MAX/100.0) Handle_RangeError();
 Store_int32(round(c*100.0));
}
double Get_Currency(void) {
 Get_int32()/100.0;
}

For general use of double, use conversion to/from a textual hexadecimal (or decimal with sufficient precision) FP notation.

void Store_double(double c) {
 char s[100];
 sprintf(s, "%a", c); // 0x1.ec7ae147ae148p+6
 // or
 sprintf(s, "%.*e", DBL_DECIMAL_DIG - 1, c); // 1.2312000000000000e+02
 Store_string(s);
}
double Get_double(void) {
 char s[100];
 Get_string(s, sizeof s);
 double x;
 sscanf(s, "%f", &x); // %f reads decimal and hexadecimal FP formats.
 return x;
}
answered Oct 15, 2016 at 13:41
Sign up to request clarification or add additional context in comments.

1 Comment

Using strings really seems to be the most portable solution for storing data.
0

Most floating point is IEEE 754, 64 bit or 32 bit. However if the floating point unit in your processor is not compatible, there's no realistic, efficient way of making it compatible, and thus programs will produce slightly different results when run on different machines. (That's actually a good test for a sound program - if results are significantly different because of floating point errors, then you are handling floating point operations badly).

You can however load and save the closest representation to IEEE 754 in a binary file, portably. Code is maintained here here

answered Oct 14, 2016 at 15:05

4 Comments

If the host computer is using a nonstandard floating-point format, then the repeated rounding error introduced by this instruction can make the result terrible. github.com/MalcolmMcLean/ieee754/blob/… It would be much better to compute with integers, for which as the question points out, there are fixed-size definitions in stdint.h that will work as expected on any compliant platform, than to rely on the very type that is assumed not to be reliable.
@Pascal Cuoq: That's in the case of scientific calculation right? In my case, I am only storing short decimals: 123.12
It depends if your FPU can represent 0.5, 0.25 and so on exactly. If not there could be a serious accumulation of error. Decimals can't be exactly represented in binary-point floating point, but the error is unlikely to matter if you only want 5 decimal places.
In my case, standard cpu I guess. Your answer answer my question but I discovered that my problem is also about endiness.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.