MCS-48: The quest for 16-bit division on the 8-bit CPU which can’t divide
IIRC, the DS18B10 (like its cousins) does not return celsius multiplied by 10 (i.e., not &#x27;153&#x27; for 15.3°C), but returns a 7 bit integer celsius value plus a sign plus a few fractional bits -- by default 1 (i.e, a +-7.1 bit format), but maybe this device has a few more bits in a secondary register -- I remember using one that had four sub-celsius bits, i.e., would output 1&#x2F;16 celsius steps (a +-7.4 bit value).  In any case, not a value multiplied by 10, but a celsius unit with binary fractional bits.<p>Am I wrong?  Looking for DS18B10 data sheet always gives me the DS18S20.  Hmm, dunno.<p>Anyway, assuming a sign + 7 bits integer + 4 bits fractional format, you can calculate inside 16 bit signed without overflow with a 3-bit shifted 9&#x2F;5 constant without overflowing, up to beyond 100°C.  With a bit of shifting, the following is quite accurate:<p><pre><code>  int16_t celsius2fahrenheit(int16_t c)
  {
    int16_t f = 0;
    f += c &lt;&lt; 4;
    f -= c;
    f -= c &gt;&gt; 1;
    f -= c &gt;&gt; 3;
    f += c &gt;&gt; 5;
    f += 32 &lt;&lt; 7;
    f &gt;&gt;= 3;
    return f;
  }
</code></pre>
Accuracy:<p><pre><code>  C=0    (int: 0),    F=32      (exact: 32,    int: 512)
  C=15.3 (int: 244),  F=59.4375 (exact: 59.54, int: 951)
  C=37   (int: 592),  F=98.625  (exact: 98.6,  int: 1578)
  C=100  (int: 1600), F=212.062 (exact: 212,   int: 3393)</code></pre>