2011-08-12 58 views
13

Estoy construyendo un carro de cálculo bastante pesado para una tienda de telas y he tenido que hacer un cálculo sobre la longitud ingresada por el usuario * el precio base por metro, pero luego verificando el resultado para ver si es un múltiplo de la longitud del patrón. Si no es un múltiplo, necesito encontrar el múltiplo más cercano de la longitud del patrón y cambiar el resultado a eso.javascript cómo saber si un número es un múltiplo de otro

También necesito poder hacer exactamente el mismo cálculo en PHP, pero si alguien puede ayudarme con las matemáticas puedo portar cualquier cosa que necesite ser traducida por mí mismo.

Estoy usando jQuery 1.6.2 y ya tengo la primera parte del cálculo hecha, solo necesito verificar el resultado de (metros * precio) con respecto a la longitud del patrón.

Cualquier ayuda muy apreciada

EDIT: todos estos cálculos implican 2 decimales, tanto para el precio y la longitud del patrón. La longitud ingresada por el usuario también puede contener decimales.

+3

No utilice aritmética de punto flotante por dinero. Convierta los precios en centavos. –

+0

lo seré, todo es atm de punto flotante porque así es como sale del DB :( – jammypeach

Respuesta

24

Uso del % (módulo) del operador en Javascript y PHP, que devuelve el resto cuando a se divide por b en a % b. El resto será cero cuando a sea un múltiplo de b.

Ej.

//Javascript 
var result = userLength * basePrice;  //Get result 
if(result % patternLength){    //Check if there is a remainder 
    var remainder = result % patternLength; //Get remainder 
    if(remainder >= patternLength/2)  //If the remainder is larger than half of patternLength, then go up to the next mulitple 
    result += patternLength - remainder; 
    else         //Else - subtract the remainder to go down 
    result -= remainder; 
} 
result = Math.round(result * 100)/100; //Round to 2 decimal places 
+1

facepalm :) Tuve una idea del módulo pero no pensé en lo que podría hacer con el resto. esto funciona para mí, muchas gracias. – jammypeach

+0

Oye, no quiero escribir un duplicado, quieres decir que escribirías un 'bool' rápido para' if (a% b) {} 'para devolver true si' b' es un multiplicador de 'a' ?? EDITAR: la respuesta a continuación explica mejor mi caso. – thednp

16

Puede usar el módulo para encontrar el resto después de una división y luego, si el resto es igual a cero, es un múltiplo.

//x and y are both integers 
var remainder = x % y; 
if (remainder == 0){ 
//x is a multiple of y 
} else { 
//x is not a multiple of y 
} 

Si los números usando su podría ser a 2DP, el módulo debería funcionar, si no, se multiplica tanto por 100 primero y luego llevar a cabo la comprobación anterior.

+5

Solo recuerda redondear el número para que no tengas ningún problema de coma flotante como http://stackoverflow.com/questions/3966484/floating-point-numbers-and-javascript-modulus-operator – Teodor

3

En javascript existe el operador de resto (similar a la mayoría de los lenguajes con una sintaxis similar a c).

Sea X = longitud e Y = precio y z = producto de x * y

var remainder = (z % x)/100; 

if (remainder === 0) { 
    // z is a multiple of x 
} 

Para obtener el x múltiple más cercana a su resultado z se podría redondear el resultado hacia arriba (o hacia abajo) utilizando ceil o funciones de piso en la biblioteca de matemáticas.

if (r >= x/2) { 
    a = Math.ceil(z/x)*x; 
} 
else { 
    a = Math.floor(z/x)*x; 
} 

Entonces redonda con dos decimales

Math.round(a/100) * 100; 
1

No estoy seguro si realmente entiende la tarea, ya que parece bastante simple para mí, pero echar un vistazo a este código PHP:

// --- input --- 
$pattern = 12.34; 
$input = 24.68; 
$precision = 2; // number of decimals 

// --- calculation --- 

// switch to "fixed point": 
$base = pow(10, $precision); 
$pattern = round($pattern * $base); 
$input = round($input * $base); 

if ($input % $pattern) { 
    // not an exact multiple 
    $input = ceil($input/$pattern) * $pattern; 
} else { 
    // it is an exact multiple 
} 

// back to normal precision: 
$pattern /= $base; 
$input /= $base; 

Esto se puede traducir fácilmente a JavaScript.

$input será el siguiente múltiplo más cercano del patrón. Si sólo necesita eso y no es necesario saber si realmente era un múltiplo también se puede simplemente hacer algo como esto:

$input = ceil($input * 100/$pattern) * $pattern/100; 
0
//roundDown to 2 decimal places function 
function r2(n) { 
    return Math.floor(n*100)/100; 
} 

neededLength = 4.55; 
price = 4.63; 
patternLength = 1.6; 

// price despite the length of the pattern 
priceSum = r2(neededLength * price); 

// calculate how many pattern lengths there must be to fit into needed length 
patternLengths = Math.floor((neededLength+patternLength)/patternLength); 
// calculate price for pattern lengths 
priceByPatternSum = r2((patternLengths * patternLength) * price); 
Cuestiones relacionadas