如何将数字(金钱)平分为x数 数字可以是一个或两个小数或没有它
,例如1000
或100.2
或112.34
我希望能够将这个数字平均分成x部分,但是如果它不是奇数,则是最后一个数字的额外数字。
例如
3856 / 3
1285.33
1285.33
1285.34
答案 0 :(得分:6)
审核其他答案
在重新检查此处提供的解决方案后,我注意到它们产生了一些奇怪的结果。
@ GeorgeMauler divideCurrencyEqually
似乎可以使用原始问题中提供的输入。但是如果你稍微改变一下,它会产生一个非常奇怪的结果......
// it appears to work
divideCurrencyEvenly(10,3)
=> [ '3.33', '3.33', '3.34' ]
// wups ...
divideCurrencyEvenly(10,6)
=> [ '1.67', '1.67', '1.67', '1.67', '3.32' ]
// hmm this one works ...
divideCurrencyEvenly(18,5)
=> [ '3.60', '3.60', '3.60', '3.60', '3.60' ]
// wups ...
divideCurrencyEvenly(100,7)
=> [ '14.29', '14.29', '14.29', '14.29', '14.29', '28.55' ]
虽然@ Barmar的解决方案似乎表现得更好......但小位......
// it appears to work
divide(10,3)
=> [ '3.33', '3.33', 3.34 ]
// acceptable, i guess
divide(10,6)
=> [ '1.66', '1.66', '1.66', '1.66', '1.66', 1.700000000000001 ]
// hmm, not so good, but still acceptable
divide(18,5)
=> [ '3.60', '3.60', '3.60', '3.60', 3.5999999999999996 ]
// as acceptable as the last two, i guess
divide(100,7)
=> [ '14.28', '14.28', '14.28', '14.28', '14.28', '14.28', 14.320000000000007 ]
3.5999999999999996
之类的数字通常是可以原谅的,因为JavaScript中的that's how float arithmetic works。
但是,我发现divide
最令人不安的是它提供了一个混合类型的数组(字符串和浮点数)。并且因为输出中的数字没有四舍五入(达到正确的精度),如果您要将结果添加到纸上,则不会返回到原来的numerator
输入 - 也就是说,除非你对结果进行四舍五入。
我们仍在争取平等......
我对上述两种解决方案也存在最后的不满。结果并不代表尽可能接近等于的分布。
如果你将100除以7,精度为2,那么@ Barmar的解决方案(修正了舍入问题)会给...
[ '14.28', '14.28', '14.28', '14.28', '14.28', '14.28', 14.32 ]
如果这些是人,而且数字代表金钱, 1人不应该支付 4便士。相反, 4人应支付 1便士更多...
[ 14.29, 14.29, 14.29, 14.29, 14.28, 14.28, 14.28 ]
尽可能接近等于
回到原点
我对解决方案不满意,所以我自己制作了一个,distribute
。
它有3个参数:精度 p
,除数 d
和分子 n
它缩放分子并找到q
所在的最大整数q * d <= n
。使用模块化划分我们知道有多少&#34;切片&#34;需要贡献q+1
。最后,每个q
或q+1
都会缩小并填充输出数组。
const fill = (n, x) =>
Array (n) .fill (x)
const concat = (xs, ys) =>
xs .concat (ys)
const quotrem = (n, d) =>
[ Math .floor (n / d)
, Math .floor (n % d)
]
const distribute = (p, d, n) =>
{ const e =
Math .pow (10, p)
const [ q, r ] =
quotrem (n * e, d)
return concat
( fill (r, (q + 1) / e)
, fill (d - r, q / e)
)
}
console .log
( distribute (2, 3, 10)
// [ 3.34, 3.33, 3.33 ]
, distribute (2, 6, 10)
// [ 1.67, 1.67, 1.67, 1.67, 1.66, 1.66 ]
, distribute (2, 5, 18)
// [ 3.6, 3.6, 3.6, 3.6, 3.6 ]
, distribute (2, 7, 100)
// [ 14.29, 14.29, 14.29, 14.29, 14.28, 14.28, 14.28 ]
)
&#13;
您将看到我将精度设为参数p
,这意味着您可以控制出现的小数位数。另请注意结果中任何数字之间的最大差异Δ
如何Δ <= 1/10^p
distribute (0, 7, 100)
=> [ 15, 15, 14, 14, 14, 14, 14 ] // Δ = 1
distribute (1, 7, 100)
=> [ 14.3, 14.3, 14.3, 14.3, 14.3, 14.3, 14.2 ] // Δ = 0.1
distribute (2, 7, 100)
=> [ 14.29, 14.29, 14.29, 14.29, 14.28, 14.28, 14.28 ] // Δ = 0.01
distribute (3, 7, 100)
=> [ 14.286, 14.286, 14.286, 14.286, 14.286, 14.285, 14.285 ] // Δ = 0.001
distribute (4, 7, 100)
=> [ 14.2858, 14.2857, 14.2857, 14.2857, 14.2857, 14.2857, 14.2857 ] // Δ = 0.0001
distribute
可以以有意义的方式部分应用。在这里,小人们可以用一种方式在餐馆里精确地分割账单......
// splitTheBill will use precision of 2 which works nice for monies
const splitTheBill = (people, money) =>
distribute (2, people, money)
// partyOfThree splits the bill between 3 people
const partyOfThree = money =>
splitTheBill (3, money)
// how much does each person pay ?
partyOfThree (67.89)
=> [ 18.93, 18.93, 18.92 ]
这是将人们分成小组的有效方式 - 同时小心不要划分个人 - 这通常会导致死亡......
// p=0 will yield only whole numbers in the result
const makeTeams = (teams, people) =>
distribute (0, teams, people)
// make 4 teams from 18 people
// how many people on each team?
makeTeams (4, 18)
=> [ 5, 5, 4, 4 ]
答案 1 :(得分:2)
function divide(numerator, divisor) {
var results = [];
var dividend = (Math.floor(numerator/divisor*100)/100).toFixed(2); // dividend with 2 decimal places
for (var i = 0; i < divisor-1; i++) {
results.push(dividend); // Put n-1 copies of dividend in results
}
results.push(numerator - (divisor-1)*dividend); // Add remainder to results
return results;
}
答案 2 :(得分:0)
听起来很简单的循环/递归。
function divideEvenly(numerator, minPartSize) {
if(numerator / minPartSize< 2) {
return [numerator];
}
return [minPartSize].concat(divideEvenly(numerator-minPartSize, minPartSize));
}
console.log(divideEvenly(1000, 333));
要使它成为两位小数的货币,在调用此函数之前将这两个数乘以100,然后将每个结果除以100并调用toFixed(2)
。
function divideCurrencyEvenly(numerator, divisor) {
var minPartSize = +(numerator / divisor).toFixed(2)
return divideEvenly(numerator*100, minPartSize*100).map(function(v) {
return (v/100).toFixed(2);
});
}
console.log(divideCurrencyEvenly(3856, 3));
//=>["1285.33", "1285.33", "1285.34"]
答案 3 :(得分:0)
由于我们谈论的是钱,通常几美分的不同并不重要,只要总数正确加起来。因此,如果您不介意一笔付款可能比其他付款高几美分,那么这是一个非常简单的分期付款解决方案。
function CalculateInstallments(total, installments) {
// Calculate Installment Payments
var pennies = total * 100;
var remainder = pennies % installments;
var otherPayments = (pennies - remainder) / installments;
var firstPayment = otherPayments + remainder;
for (var i = 0; i < installments; i++) {
if (i == 0) {
console.log("first payment = ", firstPayment / 100);
} else {
console.log("next payment = ", otherPayments / 100);
}
}
}
&#13;
由于您说您希望最后付款最高,因此您需要修改for循环中的if语句:if(i == installments-1){// last payment}
答案 4 :(得分:0)
@ user633183的distribute
上有一个问题,但仅当分隔符小于3时才会发生。
distribute(2, 2, 560.3)
// [ '280.15' , '280.14']
distribute(2, 1, 74.10)
// [ '74.09' ]
distribute(2, 1, 74.60)
// [ '74.59' ]
我将Guffa的答案改写为javascript
const distribute = (precision, divider, numerator) => {
const arr = [];
while (divider > 0) {
let amount = Math.round((numerator / divider) * Math.pow(10, precision)) / Math.pow(10, precision);
arr.push(amount);
numerator -= amount;
divider--;
}
return arr.sort((a, b) => b-a);
};
这是结果
distribute(0, 7, 100)
=> [ 15, 15, 14, 14, 14, 14, 14 ]
distribute(1, 7, 100)
=> [ 14.3, 14.3, 14.3, 14.3, 14.3, 14.3, 14.2 ]
distribute(2, 7, 100)
=> [ 14.29, 14.29, 14.29, 14.29, 14.28, 14.28, 14.28 ]
distribute(3, 7, 100)
=> [ 14.286, 14.286, 14.286, 14.286, 14.286, 14.285, 14.285 ]
distribute(4, 7, 100)
=> [ 14.2858, 14.2857, 14.2857, 14.2857, 14.2857, 14.2857, 14.2857 ]
// and of course
distribute(2, 2, 560.3)
=> [ 280.15, 280.15 ]
distribute(2, 1, 74.10)
=> [ 74.1 ]
distribute(2, 1, 74.60)
=> [ 74.6 ]
答案 5 :(得分:0)
请检查以下代码,
function Dividently(Amount, Quantity) {
var m = Amount* 100,
n = m % Quantity,
v = Math.floor(m / Quantity) / 100,
w = Math.floor(m / Quantity+ 1) / 100;
for (var i = 0, out = new Array(Quantity); i < Quantity; ++i) {
out[i] = i < n ? w : v;
}
return out;
}
var arr = Dividently(3856, 3);
Math.floor()-将数字向下舍入到最接近的整数
答案 6 :(得分:0)
如果有人正在寻找随机分布的香草JS解决方案,这是我的:
function fairDivision(resolution, numerator, denominator) {
// preserves numerator(n) integrity when dividing into denominator(d) bins
// remainders are randomly distributed into sequential bins
// resolution is number of significant digits after decimal
// (-'ve resolution for insignificant digits before decimal).
const n = numerator * Math.pow(10, resolution);
const remainder = n % denominator;
const base = (n - remainder) / denominator;
const offset = Math.floor(Math.random()*denominator); // index of first 'round-up' bin
let arr = []
let low= (offset + remainder) % denominator;
let a; let b; let c = (low < offset); //logical units
for (let i=0; i < denominator; i++) {
a = (i < low);
b = (i >= offset);
if ((a && b) || (a && c) || (b && c)) {
arr.push(base +1)
} else{
arr.push(base)
}
arr[i] = arr[i] / Math.pow(10, resolution);
}
return arr;
}
答案 7 :(得分:0)
这是基于@Thank_you 的结论,只是为了在平等的基础上划分没有小数的部分:
//n=how many groups, lot = total units
function makeTeams2(n,lot){
var div = lot/n;
var portion = Math.floor(div);
var remains = Math.round(n*((div) % 1));
var arr = [];
for(var i=0; i<n; i++) arr.push(portion);
for(var i=0; i<remains; i++) arr[i] = arr[i] + 1;
return arr;
}
// >> makeTeams2(7,100);
// >> [15,15,14,14,14,14,14]
这比@Thank_you 的“makeTeams(teams,people)”常量快一点,但我接受性能改进,因为我是初学者,我只是按照自己的方式做到了这一点,并想分享。
答案 8 :(得分:-1)
<button onclick="myFunction(3856,3)">Try it</button>
function myFunction(number,divide) {
var money = number / divide;
money = Math.ceil(money * 100) / 100;
alert(money); //1285.34
}