Ocaml 如何打印无符号64位整数
我要在Kattis身上解决这个问题 我已经在Python和C++中解决了,但是现在我想做OcAML。< /P> 这是我的密码:Ocaml 如何打印无符号64位整数,ocaml,Ocaml,我要在Kattis身上解决这个问题 我已经在Python和C++中解决了,但是现在我想做OcAML。< /P> 这是我的密码: open Printf;; let rec gcd (a : int64) (b : int64) : int64 = if not (Int64.unsigned_compare b 0L > 0) then a else gcd b (Int64.unsigned_rem a b);; try whi
open Printf;;
let rec gcd (a : int64) (b : int64) : int64 =
if not (Int64.unsigned_compare b 0L > 0) then
a
else
gcd b (Int64.unsigned_rem a b);;
try
while true;
do
let line = read_line ()
in
if String.length line > 0 then
let (nums : int64 list) = List.map (fun (s:string) : (int64) ->
(Int64.of_string (Char.escaped '0' ^ Char.escaped 'u' ^ s ))) (String.split_on_char ' ' line)
in
let rec reduce (li : int64 list) (init : int64) : (int64) =
match li with
| [] -> init
| head :: tail -> reduce tail ( Int64.unsigned_div (Int64.mul head init) (gcd head init) )
in
print_string ( Int64.to_string (reduce nums 1L) ^ "\n")
else
raise End_of_file
done;
with End_of_file -> ();;
我可以通过第一个案例,但第二个(也是最后一个)案例的结果是错误的答案。这很奇怪,因为我的逻辑在我之前两次提交的不同语言中是相同的
我猜我打印的是错误的无符号64位整数:
print_string ( Int64.to_string (reduce nums 1L) ^ "\n")
早些时候,我试过:
printf "%Lu\n" (reduce nums 1L)
但是政府说
事实上,我并不认为这个警告与我的情况有关,但我仍然感到厌倦
有什么想法吗?谢谢你的阅读 你的代码适合我。您可以考虑从头开始重新启动OCAML,然后复制/粘贴上面的代码。我就是这么做的,这对我很有效
. . .
with End_of_file -> ();;
2 3 5
30
1 2 3 4
12
399 772 163 959 242
832307365428
- : unit = ()
#
我有一个64位系统,不管它值多少钱。也就是说,对于我来说,max_int是4611686018427387903。466941151233371166不是任何输入的倍数,因此这显然是错误的。输入的数字相当大,所以我猜您只是有一个整数溢出。另一方面,你的C++代码表示1,它也不是任何一个NuMeBrs的倍数,而且也明显是错误的。 我可以看到一个可能是问题的地方:
( Int64.unsigned_div (Int64.mul head init) (gcd head init) )
当您处理输入时,init
会越来越大,然后将其乘以下一个数字。只有在你把它除以GCD之后。在该步骤中,它暂时超过64位,而您将丢失位
根据GCD的定义,head和init都可以被它整除。那么,为什么不在乘法之前将其中一个除以GCD:
(Int64.mul init (Int64.unsigned_div head (gcd head init)))
这样,中间数永远不会大于结果,接近64位限制的结果仍然会产生正确的结果。如果您给出了一个失败的示例输入,则会有所帮助。你链接到的页面上的所有示例都适用于我。也就是说,输出与链接页面上的输出相同。您的代码运行良好,我看不出任何不应该这样做的原因。关于printf,您应该使用
%Lu
修饰符。坏消息:我的代码仍然无法通过带有printf
语句的Kattis测试用例。此外,为了让我们继续思考,Kattis不会分享它的测试用例。好消息:我在OCaml程序中运行了123412341234 14441441 3555483355858858 345252345245
作为示例随机输入,然后返回466941151233371166
。我为我成功的C++程序做了同样的输入,并获得了<代码> 1 <代码>。因此,我们确实以某种方式得到了错误的输出。这可能是因为OCaml中缺少一个易于使用的“大整数”库。请澄清,max_int不应该与该程序相关,因为它使用的int64总是64位的。当然,只要考虑可能的系统差异。感谢您的洞察力!我看到他们给出了不同的输出,立即认为OCaml是错误的。不幸的是,第二个测试用例在除法后相乘时仍然没有通过。因为123412341234 14441441 3555483355858858345252345245
的最小倍数是415670427229633820981190887227101634992940430
,它需要145位。仅仅64位是无法解决的。这个问题发生了什么?对于OCaml版本4.10.0,如何获取它?
(Int64.mul init (Int64.unsigned_div head (gcd head init)))