javascript - sacar - Cómo aumentar el valor de un número al siguiente múltiplo de 10, 100, 1000, 10,000, etc.
multiplos de un numero en javascript (7)
Creo que esto sería el truco para ti:
var data = [98, 253, 87, 876, 263, -155];
var max = Math.max.apply(null, data); //
var factor = Math.pow(10, Math.floor(Math.log(Math.abs(max)) / Math.LN10));
if (factor == 0) { factor = 1; }
var magnitude = Math.ceil(max / (factor * 1.00)) * factor;
Básicamente, lo que está sucediendo arriba es lo siguiente:
- Encuentra el máximo de la muestra
- Obtenga la longitud máxima de los valores, luego eleve a una potencia de 10, es decir, 345, longitud = 3, por lo que el factor es 100
- Asegúrate de no dividir por 0
- Divida el número máximo por el factor para obtener un decimal, y tome el techo de ese número, luego multiplíquelo por el factor para obtener el número correcto de 0.
ACTUALIZACIÓN: si desea encontrar el valor mínimo (para valores negativos), simplemente voltee Math.ceil
a Math.floor
. También debe tomar el valor absoluto del mínimo para asegurarse de que no cuente el carácter negativo como parte de la cadena.
var data = [98, 253, 87, 876, 263, -155];
var min = Math.min.apply(null, data);
var factor = Math.pow(10, Math.floor(Math.log(Math.abs(max)) / Math.LN10));
if (factor == 0) { factor = 1; }
var mag = Math.floor(min / (factor * 1.00)) * factor // mag = -200;
ACTUALIZACIÓN 2: Como mucha gente ha dicho en los comentarios, no deberíamos estar usando la manipulación de cadenas. Actualicé el código para usar logaritmos en su lugar.
Tendrás que perdonar el fraseo de esta pregunta, estoy seguro de que hay una forma mejor y más concisa de preguntarlo, pero no lo sé.
Digamos que tengo un gráfico, y todos los valores del eje y son
[0,4,5,3,2,5,6]
El valor máximo es seis. Entonces me gustaría que la escala Y sea etiquetada de 0 a 10.
Teniendo en cuenta los siguientes valores
[33,26,54,23,86,23]
El valor máximo es 86, por lo que me gustaría que la escala Y pase de 0 a 90.
Ahora digamos que tengo los siguientes valores
[98,253,87, 876,263]
El máximo es 876, por lo que la escala Y debe ir de 0 a 900
Ahora he creado la siguiente función que debería darme todos los valores máximos de escala de y que necesito hasta ahora.
function padMaxValue(value){
for(var i = 1; i < 1000000000000000000; i = i * 10){
var decimalValue = value / i;
if(value === i){
return i;
}
if(decimalValue < 1 && decimalValue > 0.09){
return i;
}
}
}
Sin embargo, dados los siguientes valores
[99,123,82,189,45]
Mi función establecería el máximo de escala y a 1000
. Pero el máximo debería ser realmente 200. Me doy cuenta de que lo que realmente necesito es una forma más inteligente de aumentar el valor de i
lugar de solo multiplicarlo por 10. Necesito poder aumentar el valor de i por 10, todo el camino hasta 100. Luego, increméntelo en 100, hasta 1000. Luego, increméntelo en 1000, hasta 10,000, y así sucesivamente.
Siento que debería haber alguna forma matemática limpia y ordenada para hacer esto. Y también siento que el número 1000000000000000000
que tengo en el ciclo for revela mi desconocimiento de las matemáticas.
Anyhoot, ese es el problema. ¿Algunas ideas?
En mi opinión, las respuestas dadas son demasiado complicadas. Aquí hay una función anónima que se puede usar en MATLAB:
next = @(x,n) ceil(x/n)*n;
>> next(11,10)
ans =
20 %# 20 is the next "10" after "11")
>> next(110,100)
ans =
200 %# 200 is the next "100" after "110"
>> next([98,253,87, 876,263],100)
ans =
100 300 100 900 300
x
es el número que debe procesarse y n
es el tamaño de paso solicitado.
editar Automatización para determinar el próximo orden de magnitud también es posible
>> nextOrder = @(x) ceil(x/10.^ceil(log10(x))) * 10.^ceil(log10(x));
>> nextOrder([98,253,87,876,263])
ans =
100 1000 100 1000 1000
No hay necesidad de ir a la tierra de cuerdas, lo que podría ser incómodo si alguna vez tuvo un valor decimal.
function RoundedMax(a) {
var mx = Math.max.apply(Math, a);
if (mx == 0) {return 0};
var size = Math.floor(Math.log(Math.abs(mx)) / Math.LN10);
var magnitude = Math.pow(10, size);
var yMax = Math.ceil(mx / magnitude) * magnitude;
return yMax;
}
function RoundedMin(a) {
var mn = Math.min.apply(Math, a);
if (mn == 0) {return 0};
var size = Math.floor(Math.log(Math.abs(mn)) / Math.LN10);
var magnitude = Math.pow(10, size);
var yMin = Math.floor(mn / magnitude) * magnitude;
return yMin;
}
var arr = [-9.9,-1.23,-8.2,-2.01,-4.5,0];
document.write(RoundedMax(arr) + " " + RoundedMin(arr));
Salidas: 0 -10
.
EDITAR Actualizado a la vista de los comentarios. Ahora funciona incluso en IE8.
No me gustan las matemáticas, así que aquí hay una solución de manipulación de cadenas bastante simple / hilarante:
Encuentra el valor máximo:
var max = Math.max.apply(Math, [98,253,87, 876,263]); // 876
Toma su primer personaje
var c = max.toString()[0] // "8"
Conviértalo en un número entero y agregue 1
c = (c | 0) + 1 // 9
Convierta nuevamente a una cadena:
c = c.toString() // "9"
Agregue N - 1 ceros, donde N es la longitud de su número original:
c += Array(max.toString().length).join("0") // "900"
Convertirlo a un número entero:
c = (c | 0) // 900
¡Hecho!
En serio, usa matemáticas .
No soy muy matemático, ¡pero me tomo en serio la programación! ¡Se me ocurrió esta solución!
function getMax(max){
var mCopy = max;
var d=1;//Assuming everything is greater than 10,
while(Math.floor(mCopy) > 10){//if the number is not one digited
mCopy /= Math.pow(10,d);
d++;
}
d--;//back one digit
if(d<1)
d++;
if((Math.floor(max / Math.pow(10,d))*Math.pow(10,d))==max)
return max;
return Math.floor(max / Math.pow(10,d))*Math.pow(10,d) + Math.pow(10,d);
}
Espero que esto ayude
Terminé con:
function getGraphRange(data)
{
var max=Math.max.apply(null, data);
var min=Math.min.apply(null, data);
var maxDigits=max.toString().length;
var minDigits=min.toString().length;
var maxD=Math.pow(10,Math.max((maxDigits-1),1));
var minD=Math.pow(10,Math.max((minDigits-1),1));
var maxR=(Math.ceil(max/maxD)*maxD);
var minR=(Math.floor(min/minD)*minD);
return [minR,maxR];
}
alert(getGraphRange([11, 20, 345, 99]).join('' - ''));//10-400
alert(getGraphRange([0,4,5,3,2,5,6]).join('' - ''));//0-10
alert(getGraphRange([98,253,87,876,263]).join('' - ''));//80-900
Ya hay buenas respuestas aquí. He usado while loop para resolver el problema. La función es muy rápida y puede devolver el valor en menos de un segundo incluso para un número muy grande.
function padMaxValue(value)
{
var i = 10;
var counter = 0;
var roundMax = 10;
var copyValue = value;
//If the value is negative, convert copyValue to positive
if(value < 0) copyValue *= -1;
while(roundMax <= copyValue)
{
roundMax += i;
counter++;
if(counter == 9)
{
i *= 10;
counter = 0;
}
}
if(value < 0) roundMax *= -1;
return roundMax;
}
document.write(padMaxValue(8) + "<br>");
document.write(padMaxValue(77) + "<br>");
document.write(padMaxValue(889.65) + "<br>");
document.write(padMaxValue(-880.65) + "<br>");
document.write(padMaxValue(-765889.65) + "<br>");
document.write(padMaxValue(7888.88) + "<br>");
document.write(padMaxValue(88999887788899.099887) + "<br>");
Salida:
10
80
900
-900
-800000
8000
90000000000000