Get next smallest nearest number to a decimal

find next greater number with same set of digits python
given a number, find the next higher number which is a palindrome
smallest number with same number of digits
find next greater number in array
next greater permutation hackerrank
smallest palindrome number
how to find next greatest number in java
next smallest palindrome javascript

Introduction

For some calculations I need to find the smallest possible number I can add/subtract from a specified number without JavaScript getting in trouble with the internal used data type.

Goal

I tried to write a function which is able to return the next nearest number to VALUE in the direction of value DIR.

function nextNearest(value, direction) {
    // Special cases for value==0 or value==direction removed

    if (direction < value) {
        return value - Number.MIN_VALUE;
    } else {
        return value + Number.MIN_VALUE;
    }
}

The problem with this is, that JavaScript uses a 64-bit float type (I think) which has different minimum step sizes depending on its current exponent.

Problem in detail

The problem is the step size depending on its current exponent:

var a = Number.MIN_VALUE;

console.log(a);
// 5e-324

console.log(a + Number.MIN_VALUE);
// 1e-323 (changed, as expected)


var a = Number.MAX_VALUE;

console.log(a);
// 1.7976931348623157e+308

console.log(a - Number.MIN_VALUE);
// 1.7976931348623157e+308 (that's wrong)

console.log(a - Number.MIN_VALUE == a);
// true (which also is wrong)

Summary

So how can I find the smallest possible number I can add/subtract from a value specified in a parameter in any direction? In C++ this would be easily possible by accessing the numbers binary values.

I tried to implement Pointy's suggestion from the comments (using typed arrays). This is loosely adapted from glibc's implementation of nextafter. Should be good enough.

You can actually just increment/decrement the 64-bit integer representation of a double to get the wanted result. A mantissa overflow will overflow to the exponent which happens to be just what you want.

Since JavaScript doesn't provide a Uint64Array I had to implement a manual overflow over two 32-bit integers.

This works on little-endian architectures, but I've left out big-endian since I have no way to test it. If you need this to work on big-endian architectures you'll have to adapt this code.

// Return the next representable double from value towards direction
function nextNearest(value, direction) {
  if (typeof value != "number" || typeof direction != "number")
    return NaN;
  
  if (isNaN(value) || isNaN(direction))
    return NaN;
  
  if (!isFinite(value))
    return value;
  
  if (value === direction)
    return value;
  
  var buffer = new ArrayBuffer(8);
  var f64 = new Float64Array(buffer);
  var u32 = new Uint32Array(buffer);
  
  f64[0] = value;
  
  if (value === 0) {
    u32[0] = 1;
    u32[1] = direction < 0 ? 1 << 31 : 0;
  } else if ((value > 0) && (value < direction) || (value < 0) && (value > direction)) {
    if (u32[0]++ === 0xFFFFFFFF)
      u32[1]++;
  } else {
    if (u32[0]-- === 0)
      u32[1]--;
  }
  
  return f64[0];
}

var testCases = [0, 1, -1, 0.1,
                 -1, 10, 42e42,
                 0.9999999999999999, 1.0000000000000002,
                 10.00000762939453, // overflows between dwords
                 5e-324, -5e-324, // minimum subnormals (around zero)
                 Number.MAX_VALUE, -Number.MAX_VALUE,
                 Infinity, -Infinity, NaN];

document.write("<table><tr><th>n</th><th>next</th><th>prev</th></tr>");
testCases.forEach(function(n) {
  var next = nextNearest(n, Infinity);
  var prev = nextNearest(n, -Infinity);
  document.write("<tr><td>" + n + "</td><td>" + next + "</td><td>" + prev + "</td></tr>");
});
document.write("</table>");

Given a number, find the next smallest palindrome, Given a number, find the next smallest palindrome larger than this number. For example, if the input number is “2 3 5 4 5”, the output should be “2 3 6 3 2”. And if​  Just like before, any remaining digits before the decimal point become zeros, and any that are after the decimal point are dropped. This is called rounding up. Round to the Nearest Hundred: 3250. Identify the hundreds digit: the 2 in 3250; Identify the next smallest place value: the 5 in 3250; Is that digit greater than or equal to five? Yes, so round up.

Number.MIN_VALUE is the smallest possible representable number, not the smallest possible difference between representable numbers. Because of the way javascript handles floating point numbers the smallest possible difference between representable numbers changes with the size of the number. As the number gets larger the precision gets smaller. Thus there is no one number that will solve your problem. I suggest you either rethink how you're going to solve your problem or choose a subset of numbers to use and not the full range of MAX and MIN values.

for example: 1.7976931348623156e+308 == 1.7976931348623155e+308 //true

Also, by subtracting MIN_VALUE from MAX_VALUE you're trying to get javascript to accurately represent a number with over 600 significant figures. That's a bit too much.

Find next greater number with same set of digits, Nearest greater number by interchanging the digits · Smallest number greater than or equal to X whose sum of digits is divisible by Y · Largest number not greater  In order to test it you can generate a random number with decimals, input it within the form and select the rounding option. So, it can return any of the following: Rounded to nearest whole number; Rounded to nearest tenth; Rounded to nearest hundredth; Rounded to nearest thousandth; Rounded to nearest ten thousandths;

To find the (smallest) increment value of a given float:

For example, useful to set the step attribute of an html input type=number on the fly!

function getIncrement(number) {
  function getDecimals(number) {
    let d = parseFloat(number).toString().split('.')[1]
    if (d) {return d.length}
    return 0
  }
  return (0 + "." + Array(getDecimals(number)-1).fill(0).join("") + "1").toLocaleString('fullwide', {useGrouping:false})
}

// Tests
console.log(
  getIncrement(0.00000105),
  getIncrement(455.105),
  getIncrement(455.050000)
)

// Test
// Create input type number
function createInput(value){
  let p = document.createElement("input")
  p.type = "number"
  p.step = getIncrement(value)
  p.min = 0
  p.max = 1000
  p.value = value
  panel.appendChild(p)
}

// Tests 
createInput(0.00000105)
createInput(455.105)
createInput(455.050000)
<b>TEST.</b><br>
<div id="panel"></div>

The step attribute is set based on the base value increment.
<hr>


<b>TEST DEFAULT BEHAVIOR. </b><br>
<input type="number" min="0" max="100" value="0.00000105">
<input type="number" step="0.001" min="0" max="100" value="0.00000105">
<input type="number" step="0.000001" min="0" max="100" value="0.00000105">
<br>
This is not usable. The step atttribute needs to be set based on the value it will contains. But this require to know the value in advance and if a new dynamic value has a different decimal place, it become also unusable.

Rounding Numbers Calculator, Round numbers to thousands, hundreds, tens, ones, tenths, hundredths and Get a Widget for this Calculator Rounding calculator to round numbers up or down to any decimal place. Choose ones to round a number to the nearest dollar​. Look to the next smallest place value, the digit to the right of the place value  To round the number to the nearest: Thousand s. Type =ROUND(A1,-3) which equals 1,000. 823.7825 is closer to 1,000 than to 0 (0 is a multiple of 1,000 ) Use a negative number here because you want the rounding to happen to the left of the decimal point. The same thing applies to the next two formulas that round to hundreds and tens. Hundreds

Microsoft Excel 2010 Formulas and Functions Inside Out, next integer or multiple of significance, FLOOR() down to next smaller integer, INT() down to specified number of decimal places, ROUND() to nearest multiple,​  the smallest decimal value is : (b) because the first number besides zero is farthest to the right. (b) is equal to 23/2 mil. b<a<c

Find smallest number with same number of digits, There are two steps to get next smallest number. If you use a 0 if the front of a decimal would it still count? It won't find the nearest smaller number with same digits, it won't find anything because your joined variable does not change after  The default value is 'decimals', so that round(X,N,'decimals') is equivalent to round(X,N). Example: round(3132,2,'significant') returns 3100 , which is the closest number to 3132 that has 2 significant digits.

Using numbers and handling data, Sometimes the result of a calculation gives a number with lots of decimal calculated above you would need to round the figure to the nearest decimal place. find the first decimal place and then look at the next (smaller) decimal place to its  IV) Now sort all digits from position next to ‘d’ to the end of number. The number that we get after sorting is the output. For above example, we sort digits in bold 536974. We get “536479” which is the next greater number for input 534976. Following are the implementation of above approach.

Comments
  • You can take advantage of typed arrays to get at the low-level representation of floating point values in JavaScript. Make a 1-element Float64Array and an 8-element UInt8 array both over the same buffer.
  • DataView.getFloat() has a isLittleEndian parameter which might help. ecma-international.org/ecma-262/6.0/…
  • You're just explaining the OP's problem here. For each finite number x there is one smallest number e such as x+e != e || x-e != e. The OP is asking how to find e for a given number x.
  • Sure, but there is no answer to this problem that seems reasonable. Up at Max_Value you need at least 2. Down at min value if you add 2 you get 2. So you effectively lose all distinction between very small numbers and have to skip integers with the very big. This problem has no useful solution that doesn't include a sliding scale of values.
  • Yes that's what I'm trying to say. My number e above is really a function... Write a function epsilon(x) such as x + epsilon(x) != x. The epsilon depends on the scale of x.