Skip to content

Instantly share code, notes, and snippets.

@zr-tex8r
Created April 20, 2025 08:04
Show Gist options
  • Save zr-tex8r/ed9c8a695b48ed4478f4e7942467b74b to your computer and use it in GitHub Desktop.
Save zr-tex8r/ed9c8a695b48ed4478f4e7942467b74b to your computer and use it in GitHub Desktop.
Typst: 多倍長整数演算

bxbigcal

Typst: 多倍長整数演算

パッケージ読込

#import "@local/bxbigcal:0.2.0"

※単純にモジュールとしても使用できる(#import "bxbigcal.typ")。

使用法

  • add, sub, mul, div, mod, pow, bit-and, bit-or, bit-xor, bit-lshift, bit-rshift: 二項演算。
  • neg, not: 単項演算。
  • `cmp(«x», «y»)[int]: x < y、x = y、x > y のときに −1、0、1 を返す。
  • `str(«x»)[str]: x の十進表記の文字列。

入力

以下の値が入力として使える。

  1. int値
  2. 整数であるfloat値
  3. 十進表記のstr値
  4. 0xの接頭辞をもつ十六進表記のstr値
    ※負数は-0xを付ける。

3・4は多倍長整数を表せる。出力の整数は4の形式になる。

#import "@local/bxbigcal:0.2.0" as bc
$2^127 - 1 =
#bc.str(bc.sub(bc.pow(2, 127), 1))$
#let (
add,
sub,
mul,
div,
mod,
pow,
bit-and,
bit-or,
bit-xor,
bit-lshift,
bit-rshift,
neg,
bit-not,
cmp,
str,
) = {
import "@preview/jogs:0.2.4": *
let prefix = "bigcal"
let js-func-templates = (
operate2: ```
function !NAME!(in1, in2) {
let num1 = (typeof in1 === 'string' && in1.startsWith('-')) ?
(-BigInt(in1.substring(1))) : BigInt(in1);
let num2 = (typeof in2 === 'string' && in2.startsWith('-')) ?
(-BigInt(in2.substring(1))) : BigInt(in2);
let num0 = num1 !OP! num2;
return (num0 < 0n) ?
("-0x" + (-num0).toString(16)) : ("0x" + num0.toString(16));
}
```.text,
operate1: ```
function !NAME!(in1) {
let num1 = (typeof in1 === 'string' && in1.startsWith('-')) ?
(-BigInt(in1.substring(1))) : BigInt(in1);
let num0 = !OP! num1;
return (num0 < 0n) ?
("-0x" + (-num0).toString(16)) : ("0x" + num0.toString(16));
}
```.text,
compare: ```
function !NAME!(in1, in2) {
let num1 = (typeof in1 === 'string' && in1.startsWith('-')) ?
(-BigInt(in1.substring(1))) : BigInt(in1);
let num2 = (typeof in2 === 'string' && in2.startsWith('-')) ?
(-BigInt(in2.substring(1))) : BigInt(in2);
return (num1 === num2) ? 0 : (num1 < num2) ? -1 : 1;
}
```.text,
string: ```
function !NAME!(in1) {
let num1 = (typeof in1 === 'string' && in1.startsWith('-')) ?
(-BigInt(in1.substring(1))) : BigInt(in1);
return num1.toString();
}
```.text,
)
let functions = (
("Add", 2, "operate2", "+"),
("Sub", 2, "operate2", "-"),
("Mul", 2, "operate2", "*"),
("Div", 2, "operate2", "/"),
("Mod", 2, "operate2", "%"),
("Pow", 2, "operate2", "**"),
("And", 2, "operate2", "&"),
("Or", 2, "operate2", "|"),
("Xor", 2, "operate2", "^"),
("Lsh", 2, "operate2", "<<"),
("Rsh", 2, "operate2", ">>"),
("Neg", 1, "operate1", "-"),
("Not", 1, "operate1", "~"),
("Cmp", 2, "compare", ""),
("Str", 1, "string", ""),
)
let js-func-source(entry) = {
let (name, arity, kind, operate) = entry
js-func-templates.at(kind).replace(
"!NAME!", prefix + name
).replace(
"!OP!", operate
)
}
let bytecode = compile-js(
functions.map(js-func-source).join()
)
let typst-func(entry) = {
let (name, arity, kind, operate) = entry
let real-name = bytes(prefix + name)
if arity == 2 {
(a, b) => {
call-js-function(bytecode, real-name, a, b)
}
} else if arity == 1 {
(a) => {
call-js-function(bytecode, real-name, a)
}
}
}
functions.map(typst-func)
}
[package]
name = "bxbigcal"
version = "0.2.0"
entrypoint = "bxbigcal.typ"
compiler = "0.13.0"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment