2009-10-01 14 views
7

Non sono sicuro se questo è il modo giusto per chiedere questo o no, ma qui è il problema.Come arrotondare un decimale alla frazione più vicina?

Data una latitudine di 26.746346081599476, come trovo il numero 26.75 come il 16 ° maggiore del numero e 26.6875 come il 16 ° inferiore al numero?

26.0 
26.0625 
26.125 
26.1875 
26.25 
26.3125 
26.375 
26.4375 
26.5 
26.5625 
26.625 
26.6875 
My Number: 26.746346081599476 
26.75 
26.8125 
26.875 
26.9375 
27.0 

Sto usando JavaScript quindi una risposta in questo sarebbe utile ma non necessaria. Potrei forza bruta ma sto cercando il modo elegante per farlo.

L'immagine più grande è che voglio creare riquadri standard per un'applicazione di mappatura su cui sto lavorando. Utilizziamo le mappe di Bing e sto caricando i dati su richiesta, ogni volta che l'utente esegue il panning o lo zoom. Sarebbe bello sfruttare il caching del server per queste richieste, quindi se standardizzo le query inviate al server otterrei alcuni colpi di cache. Se non standardizzo le richieste al server, è altamente improbabile che lo stesso utente visualizzi esattamente la posizione nello stesso momento.

cui v'è una maggiore probabilità di ottenere la cache colpisce con: /path/data.json?tl=26.6875,-80.6875 & br = 26,75, -80,75 che con: /path/data.json?tl = 26,74946187679896, -80,10930061340332 & br = 26,743234270702878, -80,09607195854187

Qualsiasi fuori area che risposte sono i benvenuti pure.

risposta

14

Per trovare i multipli vicinanze della città di 1/n:

lower_bound = 1.0/n * Math.floor(n * your_number); 
upper_bound = 1.0/n * Math.ceil(n * your_number); 

si consiglia di usare un po 'di una gestione particolare se il numero è già un multiplo di 1/16.

// alternate solution so that lower_bound <= your_number < upper_bound 
lower_bound = 1.0/n * Math.floor(n * your_number); 
upper_bound = 1.0/n * Math.floor(n * your_number + 1.0); 
+0

Beat me ad esso.Ho quasi funzionato in PowerShell e sono sempre inciampato in giro per pareggiare :) – Joey

+0

@mobrule: Puoi dirmi perché la tua strada è migliore di quella di Guffa? Mi piace che il suo codice sia un po 'meno, ma sono interessato a come la gestione speciale potrebbe aiutarmi qui. – sheats

+0

A seconda di cosa si fa con i limiti, non si potrebbe voler lasciare 'lower_bound == upper_bound'. Ad esempio potresti eseguire una trasformazione lineare della scatola che hai disegnato attorno a una coordinata, e potresti avere un'espressione con '(upper_bound - lower_bound)' in un denominatore da qualche parte. – mob

9

si moltiplica il valore del 16, utilizzare il pavimento o il metodo Ceil, e dividere per 16:

var higher = Math.ceil(number * 16)/16; 
var lower = Math.floor(number * 16)/16; 
0

Qual è frazioni più piccole a cui sei interessato scissione? IE sono i sedicesimi saranno gli incrementi più piccoli?

In caso affermativo, basta moltiplicare il numero di 16. Troncarlo su un int e dividere per 16 per trovare il limite inferiore. Truncalo a un int, aggiungi 1, quindi dividi per 16 per trovare il limite superiore.

1

Suona come l'arrotondamento al 16 ° più vicino ...

rounded = Math.round(number * 16)/16; 

Si potrebbe ottenere i numeri che non sono esattamente a causa della rappresentazione galleggiante, ma che non dovrebbe importare nel tuo caso se lo si utilizza solo per la cache .

0

Un paio di strategie non ha registrato finora:

A) creare una tabella di ricerca che associa le cifre dopo la virgola al 16 ° più vicino. Usa semplicemente la precisione di cui hai bisogno (probabilmente centesimi).

B) creare una tabella di tutte le 16ths 0-1, e fare una ricerca binaria stile con il vostro numero% 1.

1
function bounds(number, numerator, denominator) { 
    var frac = denominator/numerator; 
    return { 
    lower: Math.floor(frac * number)/frac, 
    upper: Math.ceil(frac * number)/frac, 
    } 
} 


bounds(26.746346081599476,1,16) 
// returns an object with properties 
// lower : 26.6875 
// upper : 26.75 
Problemi correlati