Subversion Repositories HelenOS-historic

Rev

Rev 875 | Rev 1031 | 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.     __u64 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.     __s32 exp;
  77.     __u64 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 = 0x800000; /* 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 __u32 _float32_to_uint32_helper(float32 a)
  148. {
  149.     __u32 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. __u32 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. __s32 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 __u64 _float64_to_uint64_helper(float64 a)
  216. {
  217.     __u64 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. __u64 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. __s64 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 __u64 _float32_to_uint64_helper(float32 a)
  287. {
  288.     __u64 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. __u64 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. __s64 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. __u32 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 (__u32)_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. __s32 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 (__s32)_float64_to_uint64_helper(a);
  387. }  
  388.  
  389. /** Convert unsigned integer to float32
  390.  *
  391.  *
  392.  */
  393. float32 uint32_to_float32(__u32 i)
  394. {
  395.     int counter;
  396.     __s32 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(__s32 i)
  426. {
  427.     float32 result;
  428.  
  429.     if (i < 0) {
  430.         result = uint32_to_float32((__u32)(-i));
  431.     } else {
  432.         result = uint32_to_float32((__u32)i);
  433.     }
  434.    
  435.     result.parts.sign = i < 0;
  436.  
  437.     return result;
  438. }
  439.  
  440.  
  441. float32 uint64_to_float32(__u64 i)
  442. {
  443.     int counter;
  444.     __s32 exp;
  445.     float32 result;
  446.    
  447.     result.parts.sign = 0;
  448.     result.parts.fraction = 0;
  449.  
  450.     counter = countZeroes64(i);
  451.  
  452.     exp = FLOAT32_BIAS + 64 - counter - 1;
  453.    
  454.     if (counter == 64) {
  455.         result.binary = 0;
  456.         return result;
  457.     }
  458.    
  459.     /* Shift all to the first 31 bits (31. will be hidden 1)*/
  460.     if (counter > 33) {
  461.         i <<= counter - 1 - 32;
  462.     } else {
  463.         i >>= 1 + 32 - counter;
  464.     }
  465.  
  466.     roundFloat32(&exp, &i);
  467.  
  468.     result.parts.fraction = i >> 7;
  469.     result.parts.exp = exp;
  470.     return result;
  471. }
  472.  
  473. float32 int64_to_float32(__s64 i)
  474. {
  475.     float32 result;
  476.  
  477.     if (i < 0) {
  478.         result = uint64_to_float32((__u64)(-i));
  479.     } else {
  480.         result = uint64_to_float32((__u64)i);
  481.     }
  482.    
  483.     result.parts.sign = i < 0;
  484.  
  485.     return result;
  486. }
  487.  
  488. /** Convert unsigned integer to float64
  489.  *
  490.  *
  491.  */
  492. float64 uint32_to_float64(__u32 i)
  493. {
  494.     int counter;
  495.     __s32 exp;
  496.     float64 result;
  497.     __u64 frac;
  498.    
  499.     result.parts.sign = 0;
  500.     result.parts.fraction = 0;
  501.  
  502.     counter = countZeroes32(i);
  503.  
  504.     exp = FLOAT64_BIAS + 32 - counter - 1;
  505.    
  506.     if (counter == 32) {
  507.         result.binary = 0;
  508.         return result;
  509.     }
  510.    
  511.     frac = i;
  512.     frac <<= counter + 32 - 1;
  513.  
  514.     roundFloat64(&exp, &frac);
  515.  
  516.     result.parts.fraction = frac >> 10;
  517.     result.parts.exp = exp;
  518.  
  519.     return result;
  520. }
  521.  
  522. float64 int32_to_float64(__s32 i)
  523. {
  524.     float64 result;
  525.  
  526.     if (i < 0) {
  527.         result = uint32_to_float64((__u32)(-i));
  528.     } else {
  529.         result = uint32_to_float64((__u32)i);
  530.     }
  531.    
  532.     result.parts.sign = i < 0;
  533.  
  534.     return result;
  535. }
  536.  
  537.  
  538. float64 uint64_to_float64(__u64 i)
  539. {
  540.     int counter;
  541.     __s32 exp;
  542.     float64 result;
  543.    
  544.     result.parts.sign = 0;
  545.     result.parts.fraction = 0;
  546.  
  547.     counter = countZeroes64(i);
  548.  
  549.     exp = FLOAT64_BIAS + 64 - counter - 1;
  550.    
  551.     if (counter == 64) {
  552.         result.binary = 0;
  553.         return result;
  554.     }
  555.    
  556.     if (counter > 0) {
  557.         i <<= counter - 1;
  558.     } else {
  559.         i >>= 1;
  560.     }
  561.  
  562.     roundFloat64(&exp, &i);
  563.  
  564.     result.parts.fraction = i >> 10;
  565.     result.parts.exp = exp;
  566.     return result;
  567. }
  568.  
  569. float64 int64_to_float64(__s64 i)
  570. {
  571.     float64 result;
  572.  
  573.     if (i < 0) {
  574.         result = uint64_to_float64((__u64)(-i));
  575.     } else {
  576.         result = uint64_to_float64((__u64)i);
  577.     }
  578.    
  579.     result.parts.sign = i < 0;
  580.  
  581.     return result;
  582. }
  583.  
  584.  
  585.