Here you can find the source of doubleToS390LongBits(double ieeeDouble)
Parameter | Description |
---|---|
ieeeDouble | the IEEE double. |
public static long doubleToS390LongBits(double ieeeDouble)
//package com.java2s; /******************************************************************************* * Copyright ? 2006, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors://from w w w.ja v a2 s.co m * IBM Corporation - initial API and implementation * *******************************************************************************/ public class Main { private final static long DOUBLE_SIGN_MASK = 0x8000000000000000L; private final static long DOUBLE_EXPONENT_MASK = 0x7ff0000000000000L; private final static long DOUBLE_MANTISSA_MASK = 0x000fffffffffffffL; private final static long DOUBLE_MANTISSA_MSB_MASK = 0x0010000000000000L; private final static long DOUBLE_BIAS = 1022; private final static int S390_DOUBLE_BIAS = 64; /** * Converts an IEEE double to an S390 double (as a long). * * @param ieeeDouble the IEEE double. * @return the number as an S390 double. */ public static long doubleToS390LongBits(double ieeeDouble) { // To convert from IEEE to S390 we use the following formula: // let r = exponent % 4; q = exponent / 4; // if q == 0 then m.2^x = m.16^q // if q != 0 then m.2^x = (m.2^(r-4)).16^(q+1) for positive q, // = (m.2^-r).16^q) for negative q // Get the bit pattern long ieeeLongBits = Double.doubleToLongBits(ieeeDouble); // Test the sign bit (0 = positive, 1 = negative) boolean positive = ((ieeeLongBits & DOUBLE_SIGN_MASK) == 0); // Deal with zero straight away... if ((ieeeLongBits & 0x7fffffffffffffffL) == 0) { // + or - 0.0 return ieeeLongBits; } // Extract the exponent long exponent = ieeeLongBits & DOUBLE_EXPONENT_MASK; // shift right 52 bits to get exponent in least significant byte exponent = exponent >>> 52; // subtract the bias to get the true value exponent = exponent - DOUBLE_BIAS; // Extract the mantissa long mantissa = ieeeLongBits & DOUBLE_MANTISSA_MASK; // Now begin the conversion to S390 long remainder = Math.abs(exponent) % 4; long quotient = Math.abs(exponent) / 4; long s390Exponent = quotient; if ((exponent > 0) && (remainder != 0)) { s390Exponent = s390Exponent + 1; } // put the sign back in if (exponent < 0) { s390Exponent = -s390Exponent; } // Add the bias s390Exponent += S390_DOUBLE_BIAS; // Now adjust the mantissa part long s390Mantissa = mantissa; // for an exponent greater than -DOUBLE_BIAS, add in the implicit bit if (exponent > (-DOUBLE_BIAS)) { s390Mantissa = s390Mantissa | DOUBLE_MANTISSA_MSB_MASK; } else { // there is no implicit bit, so the mantissa is one bit to the right // of what // we would normally expect. We need to fix this for S390 s390Mantissa = s390Mantissa << 1; } // S390 Mantissa starts 4 bits left of ieee one. The first of these is // implied in // IEEE so only shift 3 places s390Mantissa = s390Mantissa << 3; if (remainder > 0) { if (exponent > 0) { // the next two lines perform the (m.2^(r-4)) part of the // conversion int shift_places = (int) (4 - remainder); s390Mantissa = s390Mantissa >>> shift_places; } else { // to avoid loss of precision when the exponent is at a minimum, // we may need to shift the mantissa four places left and // decrease the // s390 exponent by one before shifting right if ((exponent == -(DOUBLE_BIAS)) && ((s390Mantissa & 0x00f0000000000000L) == 0)) { s390Mantissa = s390Mantissa << 4; s390Exponent = s390Exponent - 1; } // the next two lines perform the m.2-r part of the conversion s390Mantissa = s390Mantissa >>> remainder; } } // An exponent of -DOUBLE_BIAS is the smallest that IEEE can do. S390 // has // a wider range, and hence may be able to normalise the mantissa more // than // is possible for IEEE // Each shift left of four bits is equivalent to multiplying by 16, // so the exponent must be reduced by 1 if (exponent == -(DOUBLE_BIAS)) { while ((s390Mantissa != 0) && ((s390Mantissa & 0x00f0000000000000L) == 0)) { s390Mantissa = s390Mantissa << 4; s390Exponent = s390Exponent - 1; } } // if the exponent is now > 127, we have an overflow since IEEE can // handle larger numbers // than S390 can. if (s390Exponent > 127) { throw new RuntimeException( //TODO need to make a proper AnyException for this "Number outside of range for double precision OS390 Float"); } else if (s390Exponent < 0) { // the number is too small to represent, set it to zero return 0L; } // Assemble the s390BitPattern long s390Double = 0L; long s390ExponentBits = s390Exponent & 0x000000000000007FL; // make sure we only deal with 7 bits // add the exponent s390Double = s390ExponentBits << 56; // shift to MSB // add the sign if (!positive) { s390Double = s390Double | DOUBLE_SIGN_MASK; } // add the mantissa s390Double = s390Double | s390Mantissa; return s390Double; } }