Link to home
Start Free TrialLog in
Avatar of djhex
djhex

asked on

Normazile float numbers

How can I Normalize two float numbers


Suppose the input of users as this

1.98 x 10E 4   = 19800
 21.22 x 10E5 = 2120000

But I need to set them as

0.19 x 10 E -5
and the second one must be 0 in the first digit and must be the same exponent
0.2122 x 10E-6 -> as this is greater than first I must move the coma of the first one

0.019 x 10 E -6
0.2122 x 10 E -6

I need to make this in a single function.


Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image

Hi djhex,

Is the user entering 1.98 x 10E4  or  19800?

If the first, you've made a whole lot of work for yourself.  If the second, the math conversion routines should normalize the value for you.

If scientific notation is required, have the user enter 1.98E4.  The math library will convert it.

Oh -- use scanf(), or better yet, sscanf() to convert the input to floating point.


Good Luck!
Kent
Avatar of djhex
djhex

ASKER

The user can enter the value as he wishes and I need to normalize it and show the output. as I showed on the example

Does scanf normalizes it automatically? Because I an giving these parameters to an assembly program

Some combination of %f and %e should work for conversions.  It's been quite a while since I've used exponential notation, but there aren't a lot of "moving parts"

"%e" is the format specifier for Exponential Notation.  "%f" might also work on the read, I don't recall.

float FloatValue;
  scanf ("%e", &FloatValue);

The normal behavior is that floating point values are normalized.



Kent

Firstly,
1.98 x 10E4 = 19800 = 0.19*10e5 (not 0.19 x 10 E -5 . This messed up my program, was getting wierd answers)
21.22 x 10E5 = 2120000 = 0.2122*10e6 (not 0.2122 x 10E-6)

Secondly,
      Normalization means to put the decimal point to the left-most non-zero digit.
      It is not depended on the second number.

      The shifting as u said takes place in binary operation as add and subract, only.
u will find it logical by reading the algorithms below.
(From Computer Organization-> By Carl Hamacher,
 Zvonko Vranesic, Safwat Zaky. Mc-Graw Hill Pub.)

Add/Subtract Rule
-----------------
     3.25 x 10 ** 3
   + 2.63 x 10 ** -1
     ---------------
1.      Choose the number with the smallest exponent and shift its mantissa right a number of steps equal to the difference in exponents.
     3.25         x 10 ** 3
   + 0.000263 x 10 ** 3
     -----------------------
2.      Set the exponent of the result equal to the larger exponent
     3.25         x 10 ** 3
   + 0.000263 x 10 ** 3
     ------------------------
                    x 10 ** 3
3.      Perform Addition and subraction of mantissa
     3.25         x 10 ** 3
   + 0.000263 x 10 ** 3
     --------------------
      3.250263 x 10 ** 3
4.      Normalize the resulting value (if neccessary).

      In the below to algorithms shifting of mantissa is not done, as u will notice.
Multiply Rule
-------------
1.      Add the exponents
2.      Multiply the mantissa
3.      Normalize the resulting value (if neccessary).

Divide Rule
-----------
1.      Subtract the exponents
2.      Divide the mantissa
3.      Normalize the resulting value (if neccessary).

******************************************
      The above said shifting is done by the processor automatically.
But I suppose U want to do it manually, using a C code.

      In C the normailzed form is different, ie the decimal point is immediatly after the left-most non-zero digit.
Thus, calls for another structure normalized float.
******************************************

#include <stdio.h>
#include <math.h>

typedef struct {
      long mantissa;            /* all digits from the left-most non-zero digit to the right-most non-zero digit */
      int pow;
} norm_float;

norm_float normalize (float f);      /* to normalize the float */
norm_float add (norm_float nf1, norm_float nf2);      
/* an illustration of shifting the mantissa using add operation */
float to_float (norm_float nf);
/* convert your normailzed_float to c_float */
void print_nf (norm_float nf);      /* prints your norm_float*/

void main()
{
      norm_float nf1, nf2, nfr;

      nf1 = normalize (1.98e4);
      printf ("nf1 = ");
      print_nf (nf1);
      printf ("\n");

      nf2 = normalize (21.22e5);
      printf ("nf2 = ");
      print_nf (nf2);
      printf ("\n");

      nfr = add (nf1, nf2);
      printf ("Sum = ");
      print_nf (nfr);
      printf ("\n");
}

norm_float normalize (float f)
{
      long t;
      float tmp;

      norm_float n_f;
      n_f.pow = 0;

      tmp = f;

      /* removing the decimal point eg:1.987 to 1987 */
      while (tmp != floor(tmp)) {
            n_f.pow ++;
            tmp *= 10;
      }

      /* extracting the mantissa */
      n_f.mantissa = (long)tmp;

      /* removing the 0's in the right eg:19800 to 198 */
      while (n_f.mantissa != 0 && n_f.mantissa%10 == 0)      
        {
            n_f.mantissa /= 10;
            n_f.pow++;
      }

      /* getting the power eg:making 198 to .198 */
      t = n_f.mantissa;
      while (t != 0) {
            t /= 10;
            n_f.pow++;
      }

      return n_f;
}

norm_float add (norm_float nf1, norm_float nf2)
{
      norm_float result;
      norm_float tmp;
      long tr;
      int nod_1 = 0,nod_2 = 0; /*nod => no of digit */

      /* counting no. of digits in mantissa */
      tmp = nf1;
      while (tmp.mantissa != 0) {
            tmp.mantissa /= 10;
            nod_1++;
      }

      /* counting no. of digits in mantissa */
      tmp = nf2;
      while (tmp.mantissa != 0) {
            tmp.mantissa /= 10;
            nod_2++;
      }

      /* the reason behind counting the digits is
      because, in the above addition algorithm, the
      shifting was to the right of mantissa of
      smallest exponent, that is padding the left
      with zeroes.
      Since this is not possible, we will pad the
      right of the mantissa of largest exponent, ie
      shifting to the left.
      But the no. of shifts is not the same.
      Eg: (When done according to above algo)
           0.3256 x 10 ** 3                  0.3256    x 10 ** 3
         + 0.263  x 10 ** -1 ==>      0.0000263 x 10 ** 3
            no of shifts = 4
          (but when using my method)
           3256            3256000
         + 263  ==>                 263
            no of shifts = 3 (forget the power for now)
      Thus, if u notice the
      no of shift = diff.in power - diff.in no of digits
      */
      /* Checking which power is greatest */
      if (abs(nf1.pow) > abs(nf2.pow)) {
            result.pow = nf1.pow;
            nf1.mantissa *= pow(10, abs( f1.pow-nf2.pow)
                                        - (nod_1-nod_2));
            tmp = nf1;
      }
      else {
            result.pow = nf2.pow;
            nf2.mantissa *= pow(10, abs( f1.pow-nf2.pow)                
                                        -(nod_2-nod_1));
            tmp = nf2;
      }
      /* performing addition */
      result.mantissa = nf1.mantissa + nf2.mantissa;

      /* normalizing result */
      tr = result.mantissa;
      while (tr != 0 && tmp.mantissa != 0) {
            tr /= 10;
            tmp.mantissa /= 10;
      }

      if (tr != 0 && tmp.mantissa == 0)
            result.pow++;
      else if (tr == 0 && tmp.mantissa != 0)
            result.pow--;

      /* remove 0's in the right eg: 599 + 11 = 600 to 6
      while (result.mantissa != 0 &&
                  result.mantissa%10 == 0)
            result.mantissa /= 10;

      return result;
}

float to_float (norm_float nf)
{
      return nf.mantissa*pow(10,nf.pow);
}

void print_nf (norm_float nf)
{
      printf ("%ld*10^%d", nf.mantissa, nf.pow);
}
Avatar of djhex

ASKER

Thank you very much to all of you. One last question that is not clear to me.


 After normalization the binary IEEE representation of the (7 or 8 bit of the exponents will be the same?)

I ask this. because I am supposed to do an addition in assembler but calling the function from C. I already made the link between assembly and C.
Explain briefly, i didnt get u
Avatar of djhex

ASKER

http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html

I tried this with the numbers

  3.25         x 10 ** 3
   + 0.000263 x 10 ** 3

These numbers suppose to have the same exponent but the exponent bits are not the same. :(

the no. are in the form
mantissa*2^exp in binary (or internal representation)

and not
mantissa*10^exp

thus not the same
Avatar of djhex

ASKER

SO I got a problem.
try this

put 1020 in the site u me
and put 520

u get the same exp
Avatar of djhex

ASKER

thats what I want to DO. My assembler function must receive the 2 float numbers and its internal repreesntation of the exponent must be equal. So in that way I can make a normal addition in assembly without having to worry about it. But as I can see I will have to do it everything from assembly

Oh, the problems are worse than you think.  :(

All of the discussion so far assumes positive values.  The rules change a bit when you consider negative numbers!


Kent
u mean to say, u need help in assembly coding or pass the two float numbers to the assembly program with their exponents being equal
kdo,
my code works fine if the nubers are -ve
Avatar of djhex

ASKER

SO I want to cry.


Hi libin_v,

It appears that the code works fine for negative exponent.   6.12E-4, etc.

What about negative value?   -6.12E+2, etc.


Kent
Just works as expected
djhex,
u mean to say, u need help in assembly coding or pass the two float numbers to the assembly program with their exponents being equal
ASKER CERTIFIED SOLUTION
Avatar of libin_v
libin_v
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
works for boths +ve and -ve floats
in my compiler float and long is 32bits
Avatar of djhex

ASKER

I didnt understand almost anything but You get the points. Please watch the assembly thread maybe you can help me.

If you or your friends have made an assembly addition without using FPU I really need it.


YOu got a feed back