title: What are the approaches to SW floating-point implementation?
body: <p>I need to be able to use floating-point arithmetic under my dev environment in C (CPU: ~12 MHz Motorola 68000). The standard library is not present, meaning it is a bare-bones C and no - it isn't gcc due to several other issues</p>
  <p>I tried getting the SoftFloat library to compile and one other 68k-specific FP library (name of which escapes me at this moment), but their dependencies cannot be resolved for this particular platform - mostly due to libc deficiencies. I spent about 8 hrs trying to overcome the linking issues, until I got to a point where I know I can't get further.</p>
  <p>However, it took mere half an hour to come up with and implement the following set of functions that emulate floating-point functionality sufficiently for my needs.</p>
  <p>The basic idea is that both fractional and non-fractional part are 16-bit integers, thus there is no bit manipulation.
  The nonfractional part has a range of [-32767, 32767] and the fractional part [-0.9999, +0.9999] - which gives us 4 digits of precision (good enough for my floating-point needs - albeit wasteful).</p>
  <p>It looks to me, like this could be used to make a faster, smaller - just 2 Bytes-big - alternative version of a float with ranges [-99, +99] and [-0.9, +0.9]</p>
  <p>The question here is, <strong>what other techniques</strong> - other than IEEE - are there to make an implementation of basic floating-point functionality (<code>+ - * /</code>) using fixed-point functionality?</p>
  <p>Later on, I will need some basic trigonometry, but there are lots of resources on net for that.</p>
  <ul>
  <li>Since the HW has 2 MBs of RAM, I don't really care if I can save 2 bytes per soft-float (say - by reserving 9 vs 7 bits in an int). Thus - 4 bytes are good enough.</li>
  <li>Also, from brief looking at the 68k instruction manual (and the cycle costs of each instruction), I made few early observations:
  <ul>
  <li>bit-shifting is slow, and unless performance is of critical importance (not the case here), I'd prefer easy debugging of my soft-float library versus 5-cycles-faster code. Besides, since this is C and not 68k ASM, it is obvious that speed is not a critical factor.</li>
  <li>8-bit operands are as slow as 16-bit (give or take a cycle in most cases), thus it looks like it does not make much sense to compress floats for the sake of performance.</li>
  </ul>
  </li>
  </ul>
  <p>What improvements / approaches would you propose to implement floating-point in C using fixed-point without any dependency on other library/code?</p>
  <p>Perhaps it would be possible to use a different approach and do the operations on frac &amp; non-frac parts at the same time?</p>
  <p>Here is the code (tested only using the calculator), please ignore the C++ - like declaration and initialization in the middle of functions (I will reformat that to C-style later):</p>
  <pre><code>inline int Pad (int f) // Pad the fractional part to 4 digits
  {
  if (f &lt; 10) return f*1000;
      else if (f &lt; 100) return f*100;
          else if (f &lt; 1000) return f*10;
              else return f;
  }
  
  //  We assume fractional parts are padded to full 4 digits 
  inline void Add (int &amp; b1, int &amp; f1,  int b2, int f2)
  {
  b1 += b2;
  f1 +=f2;
  if (f1 &gt; 9999) { b1++; f1 -=10000; }
  else if (f1 &lt; -9999) { b1--; f1 +=10000; }
  f1 = Pad (f1);
  }
  
  inline void Sub (int &amp; b1, int &amp; f1,  int b2, int f2)
  {
      // 123.1652 - 18.9752 = 104.1900
  b1 -= b2; // 105
  f1 -= f2; // -8100
  if (f1 &lt; 0) { b1--; f1 +=10000; }
  f1 = Pad (f1);
  }
  
      // ToDo: Implement a multiplication by float
  inline void Mul (int &amp; b1, int &amp; f1, int num)
  {
      // 123.9876 * 251 = 31120.8876
  b1 *=num;   // 30873
  long q = f1*num; //2478876
  int add = q/10000; // 247
  b1+=add; // 31120
  f1 = q-(add*10000);//8876
  f1 = Pad (f1);
  }
      // ToDo: Implement a division by float
  inline void Div (int &amp; b1, int &amp; f1, int num)
  {
      // 123.9876 / 25 = 4.959504
  int b2 = b1/num; // 4
  long q = b1 - (b2*num); // 23
  f1 = ((q*10000) + f1) / num; // (23000+9876) / 25 = 9595
  b1 = b2;
  f1 = Pad (f1);
  }
  </code></pre>