Subversion Repositories HelenOS-historic

Rev

Rev 857 | Rev 874 | 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.  
  33. float64 convertFloat32ToFloat64(float32 a)
  34. {
  35.     float64 result;
  36.     __u64 frac;
  37.    
  38.     result.parts.sign = a.parts.sign;
  39.     result.parts.fraction = a.parts.fraction;
  40.     result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE );
  41.    
  42.     if ((isFloat32Infinity(a))||(isFloat32NaN(a))) {
  43.         result.parts.exp = 0x7FF;
  44.         /* TODO; check if its correct for SigNaNs*/
  45.         return result;
  46.     };
  47.    
  48.     result.parts.exp = a.parts.exp + ( (int)FLOAT64_BIAS - FLOAT32_BIAS );
  49.     if (a.parts.exp == 0) {
  50.         /* normalize denormalized numbers */
  51.  
  52.         if (result.parts.fraction == 0ll) { /* fix zero */
  53.             result.parts.exp = 0ll;
  54.             return result;
  55.         }
  56.            
  57.         frac = result.parts.fraction;
  58.        
  59.         while (!(frac & (0x10000000000000ll))) {
  60.             frac <<= 1;
  61.             --result.parts.exp;
  62.         };
  63.        
  64.         ++result.parts.exp;
  65.         result.parts.fraction = frac;
  66.     };
  67.    
  68.     return result;
  69.    
  70. }
  71.  
  72. float32 convertFloat64ToFloat32(float64 a)
  73. {
  74.     float32 result;
  75.     __s32 exp;
  76.     __u64 frac;
  77.    
  78.     result.parts.sign = a.parts.sign;
  79.    
  80.     if (isFloat64NaN(a)) {
  81.        
  82.         result.parts.exp = 0xFF;
  83.        
  84.         if (isFloat64SigNaN(a)) {
  85.             result.parts.fraction = 0x800000; /* set first bit of fraction nonzero */
  86.             return result;
  87.         }
  88.    
  89.         result.parts.fraction = 0x1; /* fraction nonzero but its first bit is zero */
  90.         return result;
  91.     };
  92.  
  93.     if (isFloat64Infinity(a)) {
  94.         result.parts.fraction = 0;
  95.         result.parts.exp = 0xFF;
  96.         return result;
  97.     };
  98.  
  99.     exp = (int)a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
  100.    
  101.     if (exp >= 0xFF) {
  102.         /*FIXME: overflow*/
  103.         result.parts.fraction = 0;
  104.         result.parts.exp = 0xFF;
  105.         return result;
  106.        
  107.     } else if (exp <= 0 ) {
  108.        
  109.         /* underflow or denormalized */
  110.        
  111.         result.parts.exp = 0;
  112.        
  113.         exp *= -1; 
  114.         if (exp > FLOAT32_FRACTION_SIZE ) {
  115.             /* FIXME: underflow */
  116.             result.parts.fraction = 0;
  117.             return result;
  118.         };
  119.        
  120.         /* denormalized */
  121.        
  122.         frac = a.parts.fraction;
  123.         frac |= 0x10000000000000ll; /* denormalize and set hidden bit */
  124.        
  125.         frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
  126.        
  127.         while (exp > 0) {
  128.             --exp;
  129.             frac >>= 1;
  130.         };
  131.         result.parts.fraction = frac;
  132.        
  133.         return result;
  134.     };
  135.  
  136.     result.parts.exp = exp;
  137.     result.parts.fraction = a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
  138.     return result;
  139. }
  140.  
  141.  
  142. /** Helping procedure for converting float32 to uint32
  143.  * @param a floating point number in normalized form (no NaNs or Inf are checked )
  144.  * @return unsigned integer
  145.  */
  146. static __u32 _float32_to_uint32_helper(float32 a)
  147. {
  148.     __u32 frac;
  149.    
  150.     if (a.parts.exp < FLOAT32_BIAS) {
  151.         /*TODO: rounding*/
  152.         return 0;
  153.     }
  154.    
  155.     frac = a.parts.fraction;
  156.    
  157.     frac |= FLOAT32_HIDDEN_BIT_MASK;
  158.     /* shift fraction to left so hidden bit will be the most significant bit */
  159.     frac <<= 32 - FLOAT32_FRACTION_SIZE - 1;
  160.  
  161.     frac >>= 32 - (a.parts.exp - FLOAT32_BIAS) - 1;
  162.     if ((a.parts.sign == 1) && (frac != 0)) {
  163.         frac = ~frac;
  164.         ++frac;
  165.     }
  166.    
  167.     return frac;
  168. }
  169.  
  170. /* Convert float to unsigned int32
  171.  * FIXME: Im not sure what to return if overflow/underflow happens
  172.  *  - now its the biggest or the smallest int
  173.  */
  174. __u32 float32_to_uint32(float32 a)
  175. {
  176.     if (isFloat32NaN(a)) {
  177.         return MAX_UINT32;
  178.     }
  179.    
  180.     if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
  181.         if (a.parts.sign) {
  182.             return MIN_UINT32;
  183.         }
  184.         return MAX_UINT32;
  185.     }
  186.    
  187.     return _float32_to_uint32_helper(a);   
  188. }
  189.  
  190. /* Convert float to signed int32
  191.  * FIXME: Im not sure what to return if overflow/underflow happens
  192.  *  - now its the biggest or the smallest int
  193.  */
  194. __s32 float32_to_int32(float32 a)
  195. {
  196.     if (isFloat32NaN(a)) {
  197.         return MAX_INT32;
  198.     }
  199.    
  200.     if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
  201.         if (a.parts.sign) {
  202.             return MIN_INT32;
  203.         }
  204.         return MAX_INT32;
  205.     }
  206.     return _float32_to_uint32_helper(a);
  207. }  
  208.  
  209.  
  210. /** Helping procedure for converting float64 to uint64
  211.  * @param a floating point number in normalized form (no NaNs or Inf are checked )
  212.  * @return unsigned integer
  213.  */
  214. static __u64 _float64_to_uint64_helper(float64 a)
  215. {
  216.     __u64 frac;
  217.    
  218.     if (a.parts.exp < FLOAT64_BIAS) {
  219.         /*TODO: rounding*/
  220.         return 0;
  221.     }
  222.    
  223.     frac = a.parts.fraction;
  224.    
  225.     frac |= FLOAT64_HIDDEN_BIT_MASK;
  226.     /* shift fraction to left so hidden bit will be the most significant bit */
  227.     frac <<= 64 - FLOAT64_FRACTION_SIZE - 1;
  228.  
  229.     frac >>= 64 - (a.parts.exp - FLOAT64_BIAS) - 1;
  230.     if ((a.parts.sign == 1) && (frac != 0)) {
  231.         frac = ~frac;
  232.         ++frac;
  233.     }
  234.    
  235.     return frac;
  236. }
  237.  
  238. /* Convert float to unsigned int64
  239.  * FIXME: Im not sure what to return if overflow/underflow happens
  240.  *  - now its the biggest or the smallest int
  241.  */
  242. __u64 float64_to_uint64(float64 a)
  243. {
  244.     if (isFloat64NaN(a)) {
  245.         return MAX_UINT64;
  246.     }
  247.    
  248.     if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS)))  {
  249.         if (a.parts.sign) {
  250.             return MIN_UINT64;
  251.         }
  252.         return MAX_UINT64;
  253.     }
  254.    
  255.     return _float64_to_uint64_helper(a);   
  256. }
  257.  
  258. /* Convert float to signed int64
  259.  * FIXME: Im not sure what to return if overflow/underflow happens
  260.  *  - now its the biggest or the smallest int
  261.  */
  262. __s64 float64_to_int64(float64 a)
  263. {
  264.     if (isFloat64NaN(a)) {
  265.         return MAX_INT64;
  266.     }
  267.    
  268.     if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS)))  {
  269.         if (a.parts.sign) {
  270.             return MIN_INT64;
  271.         }
  272.         return MAX_INT64;
  273.     }
  274.     return _float64_to_uint64_helper(a);
  275. }  
  276.  
  277.  
  278.  
  279.  
  280.  
  281. /** Helping procedure for converting float32 to uint64
  282.  * @param a floating point number in normalized form (no NaNs or Inf are checked )
  283.  * @return unsigned integer
  284.  */
  285. static __u64 _float32_to_uint64_helper(float32 a)
  286. {
  287.     __u64 frac;
  288.    
  289.     if (a.parts.exp < FLOAT32_BIAS) {
  290.         /*TODO: rounding*/
  291.         return 0;
  292.     }
  293.    
  294.     frac = a.parts.fraction;
  295.    
  296.     frac |= FLOAT32_HIDDEN_BIT_MASK;
  297.     /* shift fraction to left so hidden bit will be the most significant bit */
  298.     frac <<= 64 - FLOAT32_FRACTION_SIZE - 1;
  299.  
  300.     frac >>= 64 - (a.parts.exp - FLOAT32_BIAS) - 1;
  301.     if ((a.parts.sign == 1) && (frac != 0)) {
  302.         frac = ~frac;
  303.         ++frac;
  304.     }
  305.    
  306.     return frac;
  307. }
  308.  
  309. /* Convert float to unsigned int64
  310.  * FIXME: Im not sure what to return if overflow/underflow happens
  311.  *  - now its the biggest or the smallest int
  312.  */
  313. __u64 float32_to_uint64(float32 a)
  314. {
  315.     if (isFloat32NaN(a)) {
  316.         return MAX_UINT64;
  317.     }
  318.    
  319.     if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS)))  {
  320.         if (a.parts.sign) {
  321.             return MIN_UINT64;
  322.         }
  323.         return MAX_UINT64;
  324.     }
  325.    
  326.     return _float32_to_uint64_helper(a);   
  327. }
  328.  
  329. /* Convert float to signed int64
  330.  * FIXME: Im not sure what to return if overflow/underflow happens
  331.  *  - now its the biggest or the smallest int
  332.  */
  333. __s64 float32_to_int64(float32 a)
  334. {
  335.     if (isFloat32NaN(a)) {
  336.         return MAX_INT64;
  337.     }
  338.    
  339.     if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS)))  {
  340.         if (a.parts.sign) {
  341.             return (MIN_INT64);
  342.         }
  343.         return MAX_INT64;
  344.     }
  345.     return _float32_to_uint64_helper(a);
  346. }  
  347.  
  348.  
  349. /* Convert float64 to unsigned int32
  350.  * FIXME: Im not sure what to return if overflow/underflow happens
  351.  *  - now its the biggest or the smallest int
  352.  */
  353. __u32 float64_to_uint32(float64 a)
  354. {
  355.     if (isFloat64NaN(a)) {
  356.         return MAX_UINT32;
  357.     }
  358.    
  359.     if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS)))  {
  360.         if (a.parts.sign) {
  361.             return MIN_UINT32;
  362.         }
  363.         return MAX_UINT32;
  364.     }
  365.    
  366.     return (__u32)_float64_to_uint64_helper(a);
  367. }
  368.  
  369. /* Convert float64 to signed int32
  370.  * FIXME: Im not sure what to return if overflow/underflow happens
  371.  *  - now its the biggest or the smallest int
  372.  */
  373. __s32 float64_to_int32(float64 a)
  374. {
  375.     if (isFloat64NaN(a)) {
  376.         return MAX_INT32;
  377.     }
  378.    
  379.     if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS)))  {
  380.         if (a.parts.sign) {
  381.             return MIN_INT32;
  382.         }
  383.         return MAX_INT32;
  384.     }
  385.     return (__s32)_float64_to_uint64_helper(a);
  386. }  
  387.  
  388.  
  389.