Subversion Repositories HelenOS-historic

Rev

Rev 876 | Rev 1035 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2005 Josef Cejka
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. #include "sftypes.h"
  30. #include "conversion.h"
  31. #include "comparison.h"
  32. #include "common.h"
  33.  
  34. float64 convertFloat32ToFloat64(float32 a)
  35. {
  36.     float64 result;
  37.     uint64_t frac;
  38.    
  39.     result.parts.sign = a.parts.sign;
  40.     result.parts.fraction = a.parts.fraction;
  41.     result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE );
  42.    
  43.     if ((isFloat32Infinity(a))||(isFloat32NaN(a))) {
  44.         result.parts.exp = 0x7FF;
  45.         /* TODO; check if its correct for SigNaNs*/
  46.         return result;
  47.     };
  48.    
  49.     result.parts.exp = a.parts.exp + ( (int)FLOAT64_BIAS - FLOAT32_BIAS );
  50.     if (a.parts.exp == 0) {
  51.         /* normalize denormalized numbers */
  52.  
  53.         if (result.parts.fraction == 0ll) { /* fix zero */
  54.             result.parts.exp = 0ll;
  55.             return result;
  56.         }
  57.            
  58.         frac = result.parts.fraction;
  59.        
  60.         while (!(frac & (0x10000000000000ll))) {
  61.             frac <<= 1;
  62.             --result.parts.exp;
  63.         };
  64.        
  65.         ++result.parts.exp;
  66.         result.parts.fraction = frac;
  67.     };
  68.    
  69.     return result;
  70.    
  71. }
  72.  
  73. float32 convertFloat64ToFloat32(float64 a)
  74. {
  75.     float32 result;
  76.     int32_t exp;
  77.     uint64_t frac;
  78.    
  79.     result.parts.sign = a.parts.sign;
  80.    
  81.     if (isFloat64NaN(a)) {
  82.        
  83.         result.parts.exp = 0xFF;
  84.        
  85.         if (isFloat64SigNaN(a)) {
  86.             result.parts.fraction = 0x400000; /* set first bit of fraction nonzero */
  87.             return result;
  88.         }
  89.    
  90.         result.parts.fraction = 0x1; /* fraction nonzero but its first bit is zero */
  91.         return result;
  92.     };
  93.  
  94.     if (isFloat64Infinity(a)) {
  95.         result.parts.fraction = 0;
  96.         result.parts.exp = 0xFF;
  97.         return result;
  98.     };
  99.  
  100.     exp = (int)a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
  101.    
  102.     if (exp >= 0xFF) {
  103.         /*FIXME: overflow*/
  104.         result.parts.fraction = 0;
  105.         result.parts.exp = 0xFF;
  106.         return result;
  107.        
  108.     } else if (exp <= 0 ) {
  109.        
  110.         /* underflow or denormalized */
  111.        
  112.         result.parts.exp = 0;
  113.        
  114.         exp *= -1; 
  115.         if (exp > FLOAT32_FRACTION_SIZE ) {
  116.             /* FIXME: underflow */
  117.             result.parts.fraction = 0;
  118.             return result;
  119.         };
  120.        
  121.         /* denormalized */
  122.        
  123.         frac = a.parts.fraction;
  124.         frac |= 0x10000000000000ll; /* denormalize and set hidden bit */
  125.        
  126.         frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
  127.        
  128.         while (exp > 0) {
  129.             --exp;
  130.             frac >>= 1;
  131.         };
  132.         result.parts.fraction = frac;
  133.        
  134.         return result;
  135.     };
  136.  
  137.     result.parts.exp = exp;
  138.     result.parts.fraction = a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
  139.     return result;
  140. }
  141.  
  142.  
  143. /** Helping procedure for converting float32 to uint32
  144.  * @param a floating point number in normalized form (no NaNs or Inf are checked )
  145.  * @return unsigned integer
  146.  */
  147. static uint32_t _float32_to_uint32_helper(float32 a)
  148. {
  149.     uint32_t frac;
  150.    
  151.     if (a.parts.exp < FLOAT32_BIAS) {
  152.         /*TODO: rounding*/
  153.         return 0;
  154.     }
  155.    
  156.     frac = a.parts.fraction;
  157.    
  158.     frac |= FLOAT32_HIDDEN_BIT_MASK;
  159.     /* shift fraction to left so hidden bit will be the most significant bit */
  160.     frac <<= 32 - FLOAT32_FRACTION_SIZE - 1;
  161.  
  162.     frac >>= 32 - (a.parts.exp - FLOAT32_BIAS) - 1;
  163.     if ((a.parts.sign == 1) && (frac != 0)) {
  164.         frac = ~frac;
  165.         ++frac;
  166.     }
  167.    
  168.     return frac;
  169. }
  170.  
  171. /* Convert float to unsigned int32
  172.  * FIXME: Im not sure what to return if overflow/underflow happens
  173.  *  - now its the biggest or the smallest int
  174.  */
  175. uint32_t float32_to_uint32(float32 a)
  176. {
  177.     if (isFloat32NaN(a)) {
  178.         return MAX_UINT32;
  179.     }
  180.    
  181.     if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
  182.         if (a.parts.sign) {
  183.             return MIN_UINT32;
  184.         }
  185.         return MAX_UINT32;
  186.     }
  187.    
  188.     return _float32_to_uint32_helper(a);   
  189. }
  190.  
  191. /* Convert float to signed int32
  192.  * FIXME: Im not sure what to return if overflow/underflow happens
  193.  *  - now its the biggest or the smallest int
  194.  */
  195. int32_t float32_to_int32(float32 a)
  196. {
  197.     if (isFloat32NaN(a)) {
  198.         return MAX_INT32;
  199.     }
  200.    
  201.     if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
  202.         if (a.parts.sign) {
  203.             return MIN_INT32;
  204.         }
  205.         return MAX_INT32;
  206.     }
  207.     return _float32_to_uint32_helper(a);
  208. }  
  209.  
  210.  
  211. /** Helping procedure for converting float64 to uint64
  212.  * @param a floating point number in normalized form (no NaNs or Inf are checked )
  213.  * @return unsigned integer
  214.  */
  215. static uint64_t _float64_to_uint64_helper(float64 a)
  216. {
  217.     uint64_t frac;
  218.    
  219.     if (a.parts.exp < FLOAT64_BIAS) {
  220.         /*TODO: rounding*/
  221.         return 0;
  222.     }
  223.    
  224.     frac = a.parts.fraction;
  225.    
  226.     frac |= FLOAT64_HIDDEN_BIT_MASK;
  227.     /* shift fraction to left so hidden bit will be the most significant bit */
  228.     frac <<= 64 - FLOAT64_FRACTION_SIZE - 1;
  229.  
  230.     frac >>= 64 - (a.parts.exp - FLOAT64_BIAS) - 1;
  231.     if ((a.parts.sign == 1) && (frac != 0)) {
  232.         frac = ~frac;
  233.         ++frac;
  234.     }
  235.    
  236.     return frac;
  237. }
  238.  
  239. /* Convert float to unsigned int64
  240.  * FIXME: Im not sure what to return if overflow/underflow happens
  241.  *  - now its the biggest or the smallest int
  242.  */
  243. uint64_t float64_to_uint64(float64 a)
  244. {
  245.     if (isFloat64NaN(a)) {
  246.         return MAX_UINT64;
  247.     }
  248.    
  249.     if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS)))  {
  250.         if (a.parts.sign) {
  251.             return MIN_UINT64;
  252.         }
  253.         return MAX_UINT64;
  254.     }
  255.    
  256.     return _float64_to_uint64_helper(a);   
  257. }
  258.  
  259. /* Convert float to signed int64
  260.  * FIXME: Im not sure what to return if overflow/underflow happens
  261.  *  - now its the biggest or the smallest int
  262.  */
  263. int64_t float64_to_int64(float64 a)
  264. {
  265.     if (isFloat64NaN(a)) {
  266.         return MAX_INT64;
  267.     }
  268.    
  269.     if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS)))  {
  270.         if (a.parts.sign) {
  271.             return MIN_INT64;
  272.         }
  273.         return MAX_INT64;
  274.     }
  275.     return _float64_to_uint64_helper(a);
  276. }  
  277.  
  278.  
  279.  
  280.  
  281.  
  282. /** Helping procedure for converting float32 to uint64
  283.  * @param a floating point number in normalized form (no NaNs or Inf are checked )
  284.  * @return unsigned integer
  285.  */
  286. static uint64_t _float32_to_uint64_helper(float32 a)
  287. {
  288.     uint64_t frac;
  289.    
  290.     if (a.parts.exp < FLOAT32_BIAS) {
  291.         /*TODO: rounding*/
  292.         return 0;
  293.     }
  294.    
  295.     frac = a.parts.fraction;
  296.    
  297.     frac |= FLOAT32_HIDDEN_BIT_MASK;
  298.     /* shift fraction to left so hidden bit will be the most significant bit */
  299.     frac <<= 64 - FLOAT32_FRACTION_SIZE - 1;
  300.  
  301.     frac >>= 64 - (a.parts.exp - FLOAT32_BIAS) - 1;
  302.     if ((a.parts.sign == 1) && (frac != 0)) {
  303.         frac = ~frac;
  304.         ++frac;
  305.     }
  306.    
  307.     return frac;
  308. }
  309.  
  310. /* Convert float to unsigned int64
  311.  * FIXME: Im not sure what to return if overflow/underflow happens
  312.  *  - now its the biggest or the smallest int
  313.  */
  314. uint64_t float32_to_uint64(float32 a)
  315. {
  316.     if (isFloat32NaN(a)) {
  317.         return MAX_UINT64;
  318.     }
  319.    
  320.     if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS)))  {
  321.         if (a.parts.sign) {
  322.             return MIN_UINT64;
  323.         }
  324.         return MAX_UINT64;
  325.     }
  326.    
  327.     return _float32_to_uint64_helper(a);   
  328. }
  329.  
  330. /* Convert float to signed int64
  331.  * FIXME: Im not sure what to return if overflow/underflow happens
  332.  *  - now its the biggest or the smallest int
  333.  */
  334. int64_t float32_to_int64(float32 a)
  335. {
  336.     if (isFloat32NaN(a)) {
  337.         return MAX_INT64;
  338.     }
  339.    
  340.     if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS)))  {
  341.         if (a.parts.sign) {
  342.             return (MIN_INT64);
  343.         }
  344.         return MAX_INT64;
  345.     }
  346.     return _float32_to_uint64_helper(a);
  347. }  
  348.  
  349.  
  350. /* Convert float64 to unsigned int32
  351.  * FIXME: Im not sure what to return if overflow/underflow happens
  352.  *  - now its the biggest or the smallest int
  353.  */
  354. uint32_t float64_to_uint32(float64 a)
  355. {
  356.     if (isFloat64NaN(a)) {
  357.         return MAX_UINT32;
  358.     }
  359.    
  360.     if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS)))  {
  361.         if (a.parts.sign) {
  362.             return MIN_UINT32;
  363.         }
  364.         return MAX_UINT32;
  365.     }
  366.    
  367.     return (uint32_t)_float64_to_uint64_helper(a); 
  368. }
  369.  
  370. /* Convert float64 to signed int32
  371.  * FIXME: Im not sure what to return if overflow/underflow happens
  372.  *  - now its the biggest or the smallest int
  373.  */
  374. int32_t float64_to_int32(float64 a)
  375. {
  376.     if (isFloat64NaN(a)) {
  377.         return MAX_INT32;
  378.     }
  379.    
  380.     if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS)))  {
  381.         if (a.parts.sign) {
  382.             return MIN_INT32;
  383.         }
  384.         return MAX_INT32;
  385.     }
  386.     return (int32_t)_float64_to_uint64_helper(a);
  387. }  
  388.  
  389. /** Convert unsigned integer to float32
  390.  *
  391.  *
  392.  */
  393. float32 uint32_to_float32(uint32_t i)
  394. {
  395.     int counter;
  396.     int32_t exp;
  397.     float32 result;
  398.    
  399.     result.parts.sign = 0;
  400.     result.parts.fraction = 0;
  401.  
  402.     counter = countZeroes32(i);
  403.  
  404.     exp = FLOAT32_BIAS + 32 - counter - 1;
  405.    
  406.     if (counter == 32) {
  407.         result.binary = 0;
  408.         return result;
  409.     }
  410.    
  411.     if (counter > 0) {
  412.         i <<= counter - 1;
  413.     } else {
  414.         i >>= 1;
  415.     }
  416.  
  417.     roundFloat32(&exp, &i);
  418.  
  419.     result.parts.fraction = i >> 7;
  420.     result.parts.exp = exp;
  421.  
  422.     return result;
  423. }
  424.  
  425. float32 int32_to_float32(int32_t i)
  426. {
  427.     float32 result;
  428.  
  429.     if (i < 0) {
  430.         result = uint32_to_float32((uint32_t)(-i));
  431.     } else {
  432.         result = uint32_to_float32((uint32_t)i);
  433.     }
  434.    
  435.     result.parts.sign = i < 0;
  436.  
  437.     return result;
  438. }
  439.  
  440.  
  441. float32 uint64_to_float32(uint64_t i)
  442. {
  443.     int counter;
  444.     int32_t exp;
  445.     int32_t j;
  446.     float32 result;
  447.    
  448.     result.parts.sign = 0;
  449.     result.parts.fraction = 0;
  450.  
  451.     counter = countZeroes64(i);
  452.  
  453.     exp = FLOAT32_BIAS + 64 - counter - 1;
  454.    
  455.     if (counter == 64) {
  456.         result.binary = 0;
  457.         return result;
  458.     }
  459.    
  460.     /* Shift all to the first 31 bits (31. will be hidden 1)*/
  461.     if (counter > 33) {
  462.         i <<= counter - 1 - 32;
  463.     } else {
  464.         i >>= 1 + 32 - counter;
  465.     }
  466.    
  467.     j = (uint32_t)i;
  468.     roundFloat32(&exp, &j);
  469.  
  470.     result.parts.fraction = j >> 7;
  471.     result.parts.exp = exp;
  472.     return result;
  473. }
  474.  
  475. float32 int64_to_float32(int64_t i)
  476. {
  477.     float32 result;
  478.  
  479.     if (i < 0) {
  480.         result = uint64_to_float32((uint64_t)(-i));
  481.     } else {
  482.         result = uint64_to_float32((uint64_t)i);
  483.     }
  484.    
  485.     result.parts.sign = i < 0;
  486.  
  487.     return result;
  488. }
  489.  
  490. /** Convert unsigned integer to float64
  491.  *
  492.  *
  493.  */
  494. float64 uint32_to_float64(uint32_t i)
  495. {
  496.     int counter;
  497.     int32_t exp;
  498.     float64 result;
  499.     uint64_t frac;
  500.    
  501.     result.parts.sign = 0;
  502.     result.parts.fraction = 0;
  503.  
  504.     counter = countZeroes32(i);
  505.  
  506.     exp = FLOAT64_BIAS + 32 - counter - 1;
  507.    
  508.     if (counter == 32) {
  509.         result.binary = 0;
  510.         return result;
  511.     }
  512.    
  513.     frac = i;
  514.     frac <<= counter + 32 - 1;
  515.  
  516.     roundFloat64(&exp, &frac);
  517.  
  518.     result.parts.fraction = frac >> 10;
  519.     result.parts.exp = exp;
  520.  
  521.     return result;
  522. }
  523.  
  524. float64 int32_to_float64(int32_t i)
  525. {
  526.     float64 result;
  527.  
  528.     if (i < 0) {
  529.         result = uint32_to_float64((uint32_t)(-i));
  530.     } else {
  531.         result = uint32_to_float64((uint32_t)i);
  532.     }
  533.    
  534.     result.parts.sign = i < 0;
  535.  
  536.     return result;
  537. }
  538.  
  539.  
  540. float64 uint64_to_float64(uint64_t i)
  541. {
  542.     int counter;
  543.     int32_t exp;
  544.     float64 result;
  545.    
  546.     result.parts.sign = 0;
  547.     result.parts.fraction = 0;
  548.  
  549.     counter = countZeroes64(i);
  550.  
  551.     exp = FLOAT64_BIAS + 64 - counter - 1;
  552.    
  553.     if (counter == 64) {
  554.         result.binary = 0;
  555.         return result;
  556.     }
  557.    
  558.     if (counter > 0) {
  559.         i <<= counter - 1;
  560.     } else {
  561.         i >>= 1;
  562.     }
  563.  
  564.     roundFloat64(&exp, &i);
  565.  
  566.     result.parts.fraction = i >> 10;
  567.     result.parts.exp = exp;
  568.     return result;
  569. }
  570.  
  571. float64 int64_to_float64(int64_t i)
  572. {
  573.     float64 result;
  574.  
  575.     if (i < 0) {
  576.         result = uint64_to_float64((uint64_t)(-i));
  577.     } else {
  578.         result = uint64_to_float64((uint64_t)i);
  579.     }
  580.    
  581.     result.parts.sign = i < 0;
  582.  
  583.     return result;
  584. }
  585.  
  586.  
  587.