266 * <td>{@code 0x0.0000000000001p-1022}</td> 267 * </table> 268 * @param d the {@code double} to be converted. 269 * @return a hex string representation of the argument. 270 * @since 1.5 271 * @author Joseph D. Darcy 272 */ 273 public static String toHexString(double d) { 274 /* 275 * Modeled after the "a" conversion specifier in C99, section 276 * 7.19.6.1; however, the output of this method is more 277 * tightly specified. 278 */ 279 if (!FpUtils.isFinite(d) ) 280 // For infinity and NaN, use the decimal output. 281 return Double.toString(d); 282 else { 283 // Initialized to maximum size of output. 284 StringBuffer answer = new StringBuffer(24); 285 286 if (FpUtils.rawCopySign(1.0, d) == -1.0) // value is negative, 287 answer.append("-"); // so append sign info 288 289 answer.append("0x"); 290 291 d = Math.abs(d); 292 293 if(d == 0.0) { 294 answer.append("0.0p0"); 295 } 296 else { 297 boolean subnormal = (d < DoubleConsts.MIN_NORMAL); 298 299 // Isolate significand bits and OR in a high-order bit 300 // so that the string representation has a known 301 // length. 302 long signifBits = (Double.doubleToLongBits(d) 303 & DoubleConsts.SIGNIF_BIT_MASK) | 304 0x1000000000000000L; 305 306 // Subnormal values have a 0 implicit bit; normal 307 // values have a 1 implicit bit. 308 answer.append(subnormal ? "0." : "1."); 309 310 // Isolate the low-order 13 digits of the hex 311 // representation. If all the digits are zero, 312 // replace with a single 0; otherwise, remove all 313 // trailing zeros. 314 String signif = Long.toHexString(signifBits).substring(3,16); 315 answer.append(signif.equals("0000000000000") ? // 13 zeros 316 "0": 317 signif.replaceFirst("0{1,12}$", "")); 318 319 // If the value is subnormal, use the E_min exponent 320 // value for double; otherwise, extract and report d's 321 // exponent (the representation of a subnormal uses 322 // E_min -1). 323 answer.append("p" + (subnormal ? 324 DoubleConsts.MIN_EXPONENT: 325 FpUtils.getExponent(d) )); 326 } 327 return answer.toString(); 328 } 329 } 330 331 /** 332 * Returns a {@code Double} object holding the 333 * {@code double} value represented by the argument string 334 * {@code s}. 335 * 336 * <p>If {@code s} is {@code null}, then a 337 * {@code NullPointerException} is thrown. 338 * 339 * <p>Leading and trailing whitespace characters in {@code s} 340 * are ignored. Whitespace is removed as if by the {@link 341 * String#trim} method; that is, both ASCII space and control 342 * characters are removed. The rest of {@code s} should 343 * constitute a <i>FloatValue</i> as described by the lexical 344 * syntax rules: 345 * | 266 * <td>{@code 0x0.0000000000001p-1022}</td> 267 * </table> 268 * @param d the {@code double} to be converted. 269 * @return a hex string representation of the argument. 270 * @since 1.5 271 * @author Joseph D. Darcy 272 */ 273 public static String toHexString(double d) { 274 /* 275 * Modeled after the "a" conversion specifier in C99, section 276 * 7.19.6.1; however, the output of this method is more 277 * tightly specified. 278 */ 279 if (!FpUtils.isFinite(d) ) 280 // For infinity and NaN, use the decimal output. 281 return Double.toString(d); 282 else { 283 // Initialized to maximum size of output. 284 StringBuffer answer = new StringBuffer(24); 285 286 if (Math.copySign(1.0, d) == -1.0) // value is negative, 287 answer.append("-"); // so append sign info 288 289 answer.append("0x"); 290 291 d = Math.abs(d); 292 293 if(d == 0.0) { 294 answer.append("0.0p0"); 295 } 296 else { 297 boolean subnormal = (d < DoubleConsts.MIN_NORMAL); 298 299 // Isolate significand bits and OR in a high-order bit 300 // so that the string representation has a known 301 // length. 302 long signifBits = (Double.doubleToLongBits(d) 303 & DoubleConsts.SIGNIF_BIT_MASK) | 304 0x1000000000000000L; 305 306 // Subnormal values have a 0 implicit bit; normal 307 // values have a 1 implicit bit. 308 answer.append(subnormal ? "0." : "1."); 309 310 // Isolate the low-order 13 digits of the hex 311 // representation. If all the digits are zero, 312 // replace with a single 0; otherwise, remove all 313 // trailing zeros. 314 String signif = Long.toHexString(signifBits).substring(3,16); 315 answer.append(signif.equals("0000000000000") ? // 13 zeros 316 "0": 317 signif.replaceFirst("0{1,12}$", "")); 318 319 // If the value is subnormal, use the E_min exponent 320 // value for double; otherwise, extract and report d's 321 // exponent (the representation of a subnormal uses 322 // E_min -1). 323 answer.append("p" + (subnormal ? 324 DoubleConsts.MIN_EXPONENT: 325 Math.getExponent(d) )); 326 } 327 return answer.toString(); 328 } 329 } 330 331 /** 332 * Returns a {@code Double} object holding the 333 * {@code double} value represented by the argument string 334 * {@code s}. 335 * 336 * <p>If {@code s} is {@code null}, then a 337 * {@code NullPointerException} is thrown. 338 * 339 * <p>Leading and trailing whitespace characters in {@code s} 340 * are ignored. Whitespace is removed as if by the {@link 341 * String#trim} method; that is, both ASCII space and control 342 * characters are removed. The rest of {@code s} should 343 * constitute a <i>FloatValue</i> as described by the lexical 344 * syntax rules: 345 * |