有没有 v 友 公司正好有 oracle 字符串相乘的函数 非常大的整数字符串相乘 最后结果输出为字符串 要是有阶乘的代码分享一下更好🙏
1
falsemask 2023-01-10 18:54:25 +08:00
java 的话可以直接用 BigDecimal
|
3
yangyuhan12138 OP @falsemask Java 我就没那么难受了 oracle 这边语法不熟悉 主要是
|
4
lixiang2017 2023-01-10 19:08:30 +08:00 via Android
感觉自己模拟也不麻烦
|
5
Alias4ck 2023-01-10 22:51:56 +08:00
|
6
yangyuhan12138 OP @Alias4ck 数据会十分的大 不可能用简单的乘法 只能按位相乘再相加 并且使用字符串储存结果
|
7
Alias4ck 2023-01-11 01:03:43 +08:00
@yangyuhan12138 首先你这个问题 肯定是一个 profile 的问题 ,你都没验证测试过 就说不可能 多大是多大?( stackoverflow 上的答案 也是别人的实践解决方案啊
|
8
jmc891205 2023-01-11 07:37:06 +08:00
|
9
mringg 2023-01-11 08:26:09 +08:00 via iPhone
阶乘就暴力点吧,把数据先算好,存数据库,之后查表吧。
|
10
shakoon 2023-01-11 08:36:26 +08:00
这种跟数据库查询已经没有任何关系了的运算,不建议用数据库来做,不然效率堪忧。
建议找一个现成的 java 阶乘代码来嵌进 oracle 使用。oracle 很早以前就支持 java 嵌入的,而且有好几种方式可以调用。 |
11
cccer 2023-01-11 09:44:55 +08:00
如果是几千内的阶乘,确实查表会好些
|
12
500 2023-01-11 09:58:26 +08:00
在 http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 介绍了 Split Recursive 的方式,
虽然提供的是 C# 实现但没有涉及复杂语法,可以参考一下 |
13
yangyuhan12138 OP @cccer 确实 正经人谁会这样写,但是因为这个是 我朋友公司 转正需要走做的考题...就是要用 plsql 写 ,主要看他的熟练程度 以及思维
|
14
yangyuhan12138 OP @Alias4ck 当然试过了 结果是 2500 多位 我测试的结果 图片连接 s2.loli.net/2023/01/11/Ji1UHwWPerhBauQ.png 前边加 https:// number 不可能存的下
|
15
yangyuhan12138 OP @Alias4ck 好像不用加
|
16
Alias4ck 2023-01-11 11:01:01 +08:00
@yangyuhan12138 我记得 oracle 是可以反射调用 java 程序的 2500 位的话 你这种用数据库肯定做不了
|
17
darklinden 2023-01-11 17:39:58 +08:00
大数计算的话,看下 js 的 bigint 实现?高低位运算然后使用数组存储?
|
18
yangyuhan12138 OP 思路是有的 但是公司要求用 Oracle 来解决,但是我不熟悉 Oracle 所以才来看看能不能直接捞到答案..
|
19
yangyuhan12138 OP 所以最后我还是自己实现了一下
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; |