0

I have to get input in float as +NaN or -NaN and convert to another artificial floating form called tinyfp (1 sign bit, 3 exponent bits, 4 fraction bits) for one question,

or get input in the tinyfp (each presenting +NaN or -NaN) and answer as either +NaN or -NaN

The question specifically asks

+NaN and -NaN in float should be converted to the corresponding +NaN and -NaN in tinyfp, respectively.

and

+NaN and -NaN in tinyfp should be converted to the corresponding +NaN and -NaN in float, respectively.


The first problem is, since I cannot compare NaN to anything (even itself), while I can identify if input value is NaN, I cannot distinguish between +NaN and -NaN.

Similar with second problem, when I want to answer as either +NaN or -NaN, both 0.0/0.0 and -0.0/0.0 are represented as -NaN, so I cannot answer anything as +NaN.

I tried if( input == 0.0/0.0) or (input == -0.0/0.0), and they don't work. I can try if(input != input), but then I can't distinguish +NaN and -NaN.

For the second problem, I tried return 0.0/0.0 and return -0.0/0.0, but both end up answering as -NaN. (while somehow I can get input as both nan and -nan)


So the question is, how do I check if input is +NaN or -NaN, and how do I assign +NaN and -NaN differently when I want to answer as NaN?

I'm not allowed to use any header other than stdio.h + and I can't use double format as well - only float allowed

phuclv
  • 37,963
  • 15
  • 156
  • 475
Kwon
  • 79
  • 1
  • 7
  • 1
    Even if defined in math.h, you should have a look at https://en.cppreference.com/w/c/numeric/math/nan, https://en.cppreference.com/w/c/numeric/math/signbit and https://en.cppreference.com/w/c/numeric/math/copysign and their implementation. – Giovanni Cerretani Apr 14 '19 at 12:15
  • i'm looking through the page and I can't find how they implemented it - the page only explains how to use the method they have available... is it just me not able to find how math.h does it? – Kwon Apr 14 '19 at 12:29
  • Possible implementation of `copysign` here: https://github.com/gcc-mirror/gcc/blob/master/libiberty/copysign.c – Giovanni Cerretani Apr 14 '19 at 12:36
  • i just tried it, but trying copysign(0.0/0.0, 2) gives a zero, not +nan that I need. – Kwon Apr 14 '19 at 12:47
  • @Kwon it should work. See the example in the `copysign` document. The problem is likely in your printing function – phuclv Apr 15 '19 at 00:51

3 Answers3

2

Your limitations on which functions / headers you may use give a strong impression that you are expected to directly analyze and manipulate the representations of floats. That would also presume an assumption of a specific float representation, but big-endian IEEE-754 binary32 format is a pretty good bet. I presume you've already been studying this.

You can access the representation of a float value through an unsigned char pointer:

_Bool my_isnan(float f) {
    unsigned char *bytes = (unsigned char *) &f;
    // analyze bytes[0], bytes[1], etc. ...
}

You can manipulate float representations by similar means.

I leave the details of the analyses / manipulations to you, as that seems to be the key point of the exercise, and I'm not going to do your homework for you.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
1

If you're not allowed to use math.h then you're on your own and must extract information about the float value from its binary representation. To do that you need to understand how floats are stored in the IEEE-754 format (assuming float is IEEE-754 single precision). If you don't know how floating-point types are stored then how can you construct the value in tinyfp?

So basically a float is represented as s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm with the 3 parts being sign-exponent-mantissa respectively. You just need to get the underlying bits using various ways. Then check if (eeeeeeee == 0xFF) because the largest exponent is reserved for inf and nan in IEEE-754. Now read the mantissa to know whether it's inf or nan. Getting the sign of ±inf and ±nan is trivial as you already have the sign bit. All of that have been specified in the standard, just check it

phuclv
  • 37,963
  • 15
  • 156
  • 475
0

You could use the isnan and isinf functions.

To create inf and -inf numbers you could use 1.0/0.0 (should give inf) and -1.0/0.0 (should give -inf).

Example:

#include <stdio.h>
#include <math.h>
int main() {
  double x = 1.0/0.0;
  double y = -1.0/0.0;
  double z = sqrt(-1.0);
  printf("x = %f\n", x);
  printf("y = %f\n", y);
  printf("isinf(x) = %d\n", isinf(x));
  printf("isinf(y) = %d\n", isinf(y));
  printf("isnan(x) = %d\n", isnan(x));
  printf("isnan(z) = %d\n", isnan(z));
}
Elias
  • 913
  • 6
  • 22
  • 1
    i'm not allowed to use math.h header. I have no problem with inf and -inf, the nan and -nan are the troubles – Kwon Apr 14 '19 at 12:23
  • @Kwon but why do you think there is such a thing as a "negative" nan? I think inf can be + or - but nan cannot. See https://en.wikipedia.org/wiki/IEEE_754 – Elias Apr 14 '19 at 12:30
  • 4
    @Elias NaNs have the sign bit, settable with `copysign` and readable with `signbit`. – Giovanni Cerretani Apr 14 '19 at 12:32