oracle 1000 的阶乘 最后输出字符串

2023-01-10 18:47:24 +08:00
 yangyuhan12138

有没有 v 友 公司正好有 oracle 字符串相乘的函数 非常大的整数字符串相乘 最后结果输出为字符串 要是有阶乘的代码分享一下更好🙏

2080 次点击
所在节点    程序员
19 条回复
falsemask
2023-01-10 18:54:25 +08:00
java 的话可以直接用 BigDecimal
falsemask
2023-01-10 18:54:44 +08:00
@falsemask 不好意思,没看到 oracle
yangyuhan12138
2023-01-10 18:55:19 +08:00
@falsemask Java 我就没那么难受了 oracle 这边语法不熟悉 主要是
lixiang2017
2023-01-10 19:08:30 +08:00
感觉自己模拟也不麻烦
Alias4ck
2023-01-10 22:51:56 +08:00
yangyuhan12138
2023-01-10 23:45:52 +08:00
@Alias4ck 数据会十分的大 不可能用简单的乘法 只能按位相乘再相加 并且使用字符串储存结果
Alias4ck
2023-01-11 01:03:43 +08:00
@yangyuhan12138 首先你这个问题 肯定是一个 profile 的问题 ,你都没验证测试过 就说不可能 多大是多大?( stackoverflow 上的答案 也是别人的实践解决方案啊
jmc891205
2023-01-11 07:37:06 +08:00
Karatsuba algorithm [1]
自己实现一下

[1]: https://en.wikipedia.org/wiki/Karatsuba_algorithm
mringg
2023-01-11 08:26:09 +08:00
阶乘就暴力点吧,把数据先算好,存数据库,之后查表吧。
shakoon
2023-01-11 08:36:26 +08:00
这种跟数据库查询已经没有任何关系了的运算,不建议用数据库来做,不然效率堪忧。
建议找一个现成的 java 阶乘代码来嵌进 oracle 使用。oracle 很早以前就支持 java 嵌入的,而且有好几种方式可以调用。
cccer
2023-01-11 09:44:55 +08:00
如果是几千内的阶乘,确实查表会好些
500
2023-01-11 09:58:26 +08:00
http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 介绍了 Split Recursive 的方式,
虽然提供的是 C# 实现但没有涉及复杂语法,可以参考一下
yangyuhan12138
2023-01-11 10:24:49 +08:00
@cccer 确实 正经人谁会这样写,但是因为这个是 我朋友公司 转正需要走做的考题...就是要用 plsql 写 ,主要看他的熟练程度 以及思维
yangyuhan12138
2023-01-11 10:26:23 +08:00
@Alias4ck 当然试过了 结果是 2500 多位 我测试的结果 图片连接 s2.loli.net/2023/01/11/Ji1UHwWPerhBauQ.png 前边加 https:// number 不可能存的下
yangyuhan12138
2023-01-11 10:26:51 +08:00
@Alias4ck 好像不用加
Alias4ck
2023-01-11 11:01:01 +08:00
@yangyuhan12138 我记得 oracle 是可以反射调用 java 程序的 2500 位的话 你这种用数据库肯定做不了
darklinden
2023-01-11 17:39:58 +08:00
大数计算的话,看下 js 的 bigint 实现?高低位运算然后使用数组存储?
yangyuhan12138
2023-01-12 11:17:12 +08:00
思路是有的 但是公司要求用 Oracle 来解决,但是我不熟悉 Oracle 所以才来看看能不能直接捞到答案..
yangyuhan12138
2023-01-12 11:20:01 +08:00
所以最后我还是自己实现了一下


create or replace function multiply(num1 varchar2, num2 varchar2) return varchar2 as
TYPE number_array IS VARRAY(4000) OF number;
temp_array number_array;
len1 number;
len2 number;
p1 number;
p2 number;
mul number;
ss number;
final_result varchar2(4000);
begin
temp_array := number_array();
len1 := length(num1);
len2 := length(num2);

temp_array.extend(len1 + len2);
FOR i IN 1..temp_array.count
LOOP
temp_array(i) := 0;
END LOOP;
-- Loop through the digits of the first number
FOR i IN REVERSE 1..len1
LOOP
-- Loop through the digits of the second number
FOR j IN REVERSE 1..len2
LOOP
mul := TO_NUMBER(SUBSTR(num1, i, 1)) * TO_NUMBER(SUBSTR(num2, j, 1));
p1 := i + j - 1;
p2 := i + j;
ss := mul + temp_array(p2);
temp_array(p1) := temp_array(p1) + floor(ss / 10);
temp_array(p2) := mod(ss, 10);
end loop;
end loop;

FOR i IN 1..temp_array.count
LOOP
if temp_array(i) = 0 and length(final_result) is null
then
continue ;
end if;
final_result := final_result|| temp_array(i);
END LOOP;

return final_result;
end;

create or replace function factorial(n number) return varchar2 as
result varchar2(32767) := '1';
begin
for i in 1..n
loop
result := multiply(result, to_char(i));
end loop;
return result;
end;

select factorial(1000)
from DUAL;

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/907988

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX