是否有一种简单的方法(希望小函数,而不是库)在JavaScript中添加或减去64位整数?
示例64bit int:291270990346989568
背景:我正在使用具有64位推文ID的Twitter API。我想在这些ID中添加或减去一个来操纵我从Twitter获得的结果。
答案 0 :(得分:2)
以下代码执行您所描述的内容。
拆分,添加或减去,然后重新加入......
此代码具有递增和递减功能,以及具有一些边缘情况的测试功能。当分割数字字符串并对它们进行数学运算时,你需要考虑“前导零”会发生什么,所以有一个填充函数。
感谢贾斯汀提供JSFiddle with this solution。
/*
* Prepend zeros to expand a given string to given length
*
* @var {String} numStr Number
* @var {Number} len Length to pad out to
*
* @returns {String}
*/
function pad0 (numStr,len) {
while (numStr.length < len) {
numStr = "0" + numStr;
}
return numStr
}
/*
* Decrement the given (64 bit) integer.
*
* @var {String} int64 Postive non-zero integer, as a string
*
* @returns {String}
*/
function decrInt64 (int64) {
var result = "";
var midpt = Math.floor(int64.length/2);
var upper = int64.substring(0,midpt);
var lower = int64.substring(midpt);
var upperVal = new Number(upper);
var lowerVal = new Number(lower);
if (lowerVal == 0) {
if (upperVal == 0) {
// We don't support negative numbers
result = "*ERROR*"
}
else {
// borrow 1
result = pad0((--upperVal).toString(),upper.length) +
(new Number("1"+lower) - 1).toString();
}
}
else {
var newLower = (lowerVal - 1).toString();
result = upper + pad0(newLower,lower.length);
}
alert(result);
}
/*
* Increment the given (64 bit) integer.
*
* @var {String} int64 Postive, as a string
*
* @returns {String}
*/
function incrInt64 (int64) {
var result = "";
var midpt = Math.floor(int64.length/2);
var upper = int64.substring(0,midpt);
var lower = int64.substring(midpt);
var upperVal = new Number(upper);
var lowerVal = new Number(lower);
var newLower = (++lowerVal).toString();
// Did we overflow?
if (lower.length < newLower.length) {
// Yes, carry the 1
result = (++upperVal).toString() + newLower.substring(1);
}
else {
result = upper + pad0(newLower,lower.length);
}
alert(result);
}
// Test function
window.displaymessage= function ()
{
decrInt64("291270990046989568");
incrInt64("291270990046989568");
decrInt64("000000000000000000");
incrInt64("000000000000000000");
decrInt64("000000001000000000");
incrInt64("000000001000000000");
decrInt64("099999999999999999");
incrInt64("099999999999999999");
decrInt64("999999999999999999");
incrInt64("999999999999999999");
}
答案 1 :(得分:1)
添加整数格式的字符串(基数10)不定长度可以通过将字符串拆分为9个字符的段来计算+
或-
为此,然后移动到前9个字符。这是因为最大的9个字符编号999999999
是32位安全的(就像我在减法中使用的1999999999
一样)。
以下代码有3个函数,单词 integer 假定为整数格式字符串。
addAsString
,带两个非负整数x
和y
,返回x + y
subtractAsString
,取两个非负整数x
和y
,|x| >= |y|
,返回x - y
addORsub
,任意两个整数x
和y
,返回x + y
我试图通过代码
中的注释来解释发生了什么// Indefinate length addition
function addAsString(x, y) { // x, y strings
var s = '';
if (y.length > x.length) { // always have x longer
s = x;
x = y;
y = s;
}
s = (parseInt(x.slice(-9),10) + parseInt(y.slice(-9),10)).toString(); // add last 9 digits
x = x.slice(0,-9); // cut off last 9 digits
y = y.slice(0,-9);
if (s.length > 9) { // if >= 10, add in the 1
if (x === '') return s; // special case (e.g. 9+9=18)
x = addAsString(x, '1');
s = s.slice(1);
} else if (x.length) { // if more recursions to go
while (s.length < 9) { // make sure to pad with 0s
s = '0' + s;
}
}
if (y === '') return x + s; // if no more chars then done, return
return addAsString(x, y) + s; // else recurse, next digit
}
// Indefinate length subtraction (x - y, |x| >= |y|)
function subtractAsString(x, y) {
var s;
s = (parseInt('1'+x.slice(-9),10) - parseInt(y.slice(-9),10)).toString(); // subtract last 9 digits
x = x.slice(0,-9); // cut off last 9 digits
y = y.slice(0,-9);
if (s.length === 10 || x === '') { // didn't need to go mod 1000000000
s = s.slice(1);
} else { // went mod 1000000000, inc y
if (y.length) { // only add if makes sense
y = addAsString(y, '1');
} else { // else set
y = '1';
}
if (x.length) {
while (s.length < 9) { // pad s
s = '0' + s;
}
}
}
if (y === '') { // finished
s = (x + s).replace(/^0+/,''); // dont return all 0s
return s;
}
return subtractAsString(x, y) + s;
}
// Indefinate length addition or subtraction (via above)
function addORsub(x, y) {
var s = '';
x = x.replace(/^(-)?0+/,'$1').replace(/^-?$/,'0'); // -000001 = -1
y = y.replace(/^(-)?0+/,'$1').replace(/^-?$/,'0'); // -000000 = 0
if (x[0] === '-') { // x negative
if (y[0] === '-') { // if y negative too
return '-' + addAsString(x.slice(1), y.slice(1)); // return -(|x|+|y|)
}
return addORsub(y, x); // else swap
}
if (y[0] === '-') { // x positive, y negative
s = y.slice(1);
if (s.length < x.length || (s.length === x.length && s < x)) return subtractAsString(x, s) || '0'; // if |x|>|y|, return x-y
if (s === x) return '0'; // equal then 0
s = subtractAsString(s, x); // else |x|<|y|
s = (s && '-' + s) || '0';
return s; // return -(|y|-x)
}
return addAsString(x, y); // x, y positive, return x+y
}
示例用法(fiddle)
var i = addORsub('291270990346989568', '1'); // add
i === '291270990346989569';
i = addORsub('291270990346989568', '-1'); // subtract
i === '291270990346989567';