fork download
  1. /* package whatever; // don't place package name! */
  2.  
  3. import java.util.*;
  4. import java.lang.*;
  5. import java.io.*;
  6.  
  7. /* Name of the class has to be "Main" only if the class is public. */
  8. class Ideone
  9. {
  10. public static void main (String[] args) throws java.lang.Exception
  11. {
  12. // your code goes here
  13. // }
  14.  
  15. // https://stackoverflow.com/questions/44008357/adding-and-subtracting-exact-values-to-float
  16.  
  17. //public class Toy {
  18. // public static void main(String args[]) {
  19. int length = 0x82000000;
  20. int x = length >>> 24;
  21. int y = (length >>> 24) & 0xFF;
  22.  
  23. System.out.println("length = " + length + ", x = " + x + ", y = " + y);
  24.  
  25. float float0 = 1.5f;
  26. float float1 = 1.5000001f;
  27. float float2 = 1.5000002f;
  28. float float4 = 1.5000004f;
  29. float float5 = 1.5000005f;
  30.  
  31. // testLeaps(float0, float4);
  32. // testLeaps(0, float5);
  33. // testLeaps(0, -float1);
  34. // testLeaps(-float1, 0);
  35.  
  36. System.out.println(Math.nextAfter(-float1, Float.POSITIVE_INFINITY));
  37. System.out.println(INT_POWER_MASK & Float.floatToIntBits(-float0));
  38. System.out.println(INT_POWER_MASK & Float.floatToIntBits(float0));
  39. // testLeaps(-float1, -float0);
  40. testLeaps(-float0, 0);
  41. testLeaps(float0, 0);
  42. }
  43.  
  44. public static void testLeaps(float value, float destination) {
  45. System.out.println("optLeaps(" + value + ", " + destination + ") = " + optLeaps(value, destination));
  46. System.out.println("getLeaps(" + value + ", " + destination + ") = " + getLeaps(value, destination));
  47. }
  48.  
  49. public static final int INT_POWER_MASK = 0x7f800000 | 0x007fffff; // ~0x80000000
  50. /**
  51.   * Retrieves the integer difference between two float-point values according to
  52.   * the IEEE 754 floating-point "single format" bit layout.
  53.   *
  54.   * <pre>
  55.   * mask 0x80000000 | 0x7f800000 | 0x007fffff
  56.   * sign | exponent (8 bits) | coefficient/significand/mantissa/fraction (23 bits)
  57.   * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  58.   * | | | |
  59.   * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  60.   * 31 30 23 22 0
  61.   * 0x7fc00000 => NaN
  62.   * 0x7f800000 +Infinity
  63.   * 0xff800000 -Infinity
  64.   * </pre>
  65.   *
  66.   * Using base (radix) 10, the numerical value of such a float type number is
  67.   * `(-1)^sign x coefficient x 10^exponent`, so the coefficient is a key factor
  68.   * to calculation of leaps coefficient.
  69.   *
  70.   * @param value the first operand
  71.   * @param destination the second operand
  72.   * @return the integer span from {@code value} to {@code destination}
  73.   * @see <a href="https://e...content-available-to-author-only...a.org/wiki/Single-precision_floating-point_format">sign.exponent.mantissa</a>
  74.   */
  75. public static int optLeaps(float value, float destination) {
  76. // TODO process possible cases for some special inputs.
  77.  
  78. int valueBits = Float.floatToIntBits(value); // IEEE 754 floating-point "single format" bit layout
  79. int destinationBits = Float.floatToIntBits(destination); // IEEE 754 floating-point "single format" bit layout
  80. int leaps; // Float.intBitsToFloat();
  81. if ((destinationBits ^ valueBits) >= 0) {
  82. leaps = Math.abs(destinationBits - valueBits);
  83. } else {
  84. leaps = (INT_POWER_MASK & destinationBits) + (INT_POWER_MASK & valueBits);
  85. }
  86. return leaps;
  87. }
  88.  
  89. public static int getLeaps(float value, float destination) {
  90. int leaps = 0;
  91. float signum = Math.signum(destination - value);
  92.  
  93. // float direction = Float.POSITIVE_INFINITY * signum;
  94. // while (value * signum < destination * signum) {
  95. // value = Math.nextAfter(value, direction); // Float.POSITIVE_INFINITY * direction
  96. // leaps++;
  97. // }
  98.  
  99. if (0 == signum) {
  100. return 0;
  101. }
  102. if (0 < signum) {
  103. while (value < destination) {
  104. value = Math.nextAfter(value, Float.POSITIVE_INFINITY);
  105. leaps++;
  106. }
  107. } else {
  108. while (value > destination) {
  109. value = Math.nextAfter(value, Float.NEGATIVE_INFINITY);
  110. leaps++;
  111. }
  112. }
  113. return leaps;
  114. }
  115.  
  116. // may optimiaze to reduce the elapsed time by roughly half
  117. //}
  118. }
Time limit exceeded #stdin #stdout 5s 2317312KB
stdin
Standard input is empty
stdout
length = -2113929216, x = 130, y = 130
-1.5
1069547520
1069547520
optLeaps(-1.5, 0.0) = 1069547520
getLeaps(-1.5, 0.0) = 1069547520
optLeaps(1.5, 0.0) = 1069547520