Subversion Repositories HelenOS-historic

Rev

Rev 865 | Rev 875 | 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.    
  390. /** Convert unsigned integer to float32
  391.  *
  392.  *
  393.  */
  394. float32 uint32_to_float32(__u32 i)
  395. {
  396.     int counter;
  397.     __s32 exp;
  398.     float32 result;
  399.    
  400.     result.parts.sign = 0;
  401.     result.parts.fraction = 0;
  402.  
  403.     counter = countZeroes32(i);
  404.  
  405.     exp = FLOAT32_BIAS + 32 - counter - 1;
  406.    
  407.     if (counter == 32) {
  408.         result.binary = 0;
  409.         return result;
  410.     }
  411.    
  412.     if (counter > 0) {
  413.         i <<= counter - 1;
  414.     } else {
  415.         i >>= 1;
  416.     }
  417.  
  418.     roundFloat32(&exp, &i);
  419.  
  420.     result.parts.fraction = i >> 7;
  421.     result.parts.exp = exp;
  422.  
  423.     return result;
  424. }
  425.  
  426. float32 int32_to_float32(__s32 i)
  427. {
  428.     float32 result;
  429.  
  430.     if (i < 0) {
  431.         result = uint32_to_float32((__u32)(-i));
  432.     } else {
  433.         result = uint32_to_float32((__u32)i);
  434.     }
  435.    
  436.     result.parts.sign = i < 0;
  437.  
  438.     return result;
  439. }
  440.  
  441.  
  442. float32 uint64_to_float32(__u64 i)
  443. {
  444. }
  445.  
  446. float32 int64_to_float32(__s64 i)
  447. {
  448.     float32 result;
  449.  
  450.     if (i < 0) {
  451.         result = uint64_to_float32((__u64)(-i));
  452.     } else {
  453.         result = uint64_to_float32((__u64)i);
  454.     }
  455.    
  456.     result.parts.sign = i < 0;
  457.  
  458.     return result;
  459. }
  460.