2009-10-01 12 views
7

Không chắc đó có phải là cách đúng để hỏi điều này hay không nhưng đây là vấn đề.Làm thế nào để làm tròn một số thập phân đến phân số gần nhất?

Với vĩ độ 26.746346081599476, làm cách nào để tìm số 26.75 là số 16 lớn hơn số và 26.6875 làm số 16 thấp hơn số?

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 

Tôi đang sử dụng JavaScript để câu trả lời có thể hữu ích nhưng không cần thiết. Tôi có thể bạo lực nhưng tôi đang tìm cách thanh lịch để làm điều đó.

Ảnh lớn hơn là tôi muốn tạo lát tiêu chuẩn cho ứng dụng bản đồ mà tôi đang làm việc. Chúng tôi đang sử dụng các bản đồ Bing và tôi đang tải dữ liệu theo yêu cầu, mỗi khi người dùng mở hoặc phóng to. Sẽ rất tốt nếu tận dụng bộ đệm ẩn của máy chủ cho các yêu cầu này, vì vậy nếu tôi chuẩn hóa các truy vấn được gửi đến máy chủ, tôi sẽ nhận được một số lần truy cập bộ nhớ cache. Nếu tôi không tiêu chuẩn hóa các yêu cầu đến máy chủ, rất khó có khả năng là cùng một người dùng sẽ xem chính xác một số vị trí cùng một lúc.

Vì vậy, có một cơ hội cao để lấy bộ nhớ cache chạm với: /path/data.json?tl=26.6875,-80.6875 & BR = 26,75, -80,75 hơn với: /path/data.json?tl = 26.74946187679896, -80.10930061340332 & br = 26.743234270702878, -80.09607195854187

Bất kỳ câu trả lời nào ngoài hộp cũng được chào đón.

Trả lời

14

Để tìm bội vực gần 1/n:

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

Bạn có thể muốn sử dụng một số xử lý đặc biệt nếu số của bạn đã là một bội số của 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

đánh bại tôi vào nó.Tôi gần như đã làm cho nó hoạt động trong PowerShell và luôn luôn vấp phải vòng tới thậm chí :) – Joey

+0

@mobrule: Bạn có thể cho tôi biết tại sao cách của bạn tốt hơn Guffa? Tôi thích rằng anh ấy là một chút ít mã nhưng tôi quan tâm đến cách xử lý đặc biệt sẽ giúp tôi ở đây. – sheats

+0

Tùy thuộc vào những gì bạn làm với các giới hạn, bạn có thể không muốn để cho 'lower_bound == upper_bound'. Ví dụ, bạn có thể thực hiện một số phép chuyển đổi tuyến tính của hộp bạn vẽ xung quanh một tọa độ, và bạn có thể có một biểu thức với '(upper_bound - lower_bound)' trong một mẫu số ở đâu đó. – mob

9

Bạn nhân giá trị bằng 16, sử dụng sàn hoặc phương pháp ceil, và chia cho 16:

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

các phần nhỏ nhất bạn quan tâm về chia nhỏ là gì? IE là 16th sẽ là những gia số nhỏ nhất?

Nếu có, chỉ cần nhân số của bạn với 16. Cắt nó thành số int và chia cho 16 để tìm giới hạn dưới. Trunc nó vào một int, thêm 1, sau đó chia cho 16 để tìm giới hạn trên.

1

Âm thanh như làm tròn đến 16 khu vực gần ...

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

Bạn có thể có được con số mà không phải là chính xác vì các đại diện phao, nhưng đó không phải vấn đề trong trường hợp của bạn nếu bạn sử dụng nó chỉ cho bộ nhớ đệm .

0

Một vài chiến lược chưa được đăng cho đến thời điểm này:

A) tạo bảng tra cứu ánh xạ các chữ số sau dấu thập phân đến số 16 gần nhất. Chỉ cần sử dụng bất kỳ độ chính xác nào bạn cần (có thể là hàng trăm).

B) tạo ra một bảng của tất cả các 16ths 0-1, và thực hiện tìm kiếm phong cách nhị phân với số điện thoại của% 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