利用字串實現高精度數值運算(一)
由於Oracle的數值型別的最大精度只有38位,因此對於高精度的數值計算就需要使用其他的方法來實現。
這篇文章利用字串來儲存高精度數值,並實現了兩個字串中數值的運算。
這篇描述兩個字串相加。
其實在以前處理超大數值的時候,寫過一個字串相加的函式,不過當時這個函式只是處理正整數的相加,沒有考慮小數的情況。詳細描述可以參考:http://yangtingkun.itpub.net/post/468/241044
當前面臨的問題則主要是小數精度的問題。不過這並不影響對原有程式碼的重用,只需要在原有的程式碼外面巢狀一層,分別對整數部分和小數部分進行運算,並最終將結果合併起來即可。
SQL> CREATE OR REPLACE FUNCTION F_STR_ADD (P_STR1 IN VARCHAR2, P_STR2 IN VARCHAR2) RETURN VARCHAR2 AS
2 V_INTEGER_STR1 VARCHAR2(32767) := NVL(
3 SUBSTR(P_STR1, 1,
4 CASE INSTR(P_STR1, '.') WHEN 0 THEN LENGTH(P_STR1) ELSE INSTR(P_STR1, '.') - 1 END
5 ), 0);
6 V_INTEGER_STR2 VARCHAR2(32767) := NVL(
7 SUBSTR(P_STR2, 1,
8 CASE INSTR(P_STR2, '.') WHEN 0 THEN LENGTH(P_STR2) ELSE INSTR(P_STR2, '.') - 1 END
9 ), 0);
10 V_OTHER_STR1 VARCHAR2(32767) := CASE INSTR(P_STR1, '.')
11 WHEN 0 THEN NULL ELSE SUBSTR(P_STR1, INSTR(P_STR1, '.') + 1) END;
12 V_OTHER_STR2 VARCHAR2(32767) := CASE INSTR(P_STR2, '.')
13 WHEN 0 THEN NULL ELSE SUBSTR(P_STR2, INSTR(P_STR2, '.') + 1) END;
14 V_LENGTH_OTHER_1 NUMBER := NVL(LENGTH(V_OTHER_STR1), 0);
15 V_LENGTH_OTHER_2 NUMBER := NVL(LENGTH(V_OTHER_STR2), 0);
16 V_RESULT VARCHAR2(32767);
17
18 FUNCTION F_ADD_STR(P_ADD1 IN VARCHAR2, P_ADD2 IN VARCHAR2) RETURN VARCHAR2 AS
19 V_LENGTH1 NUMBER DEFAULT LENGTH(P_ADD1);
20 V_LENGTH2 NUMBER DEFAULT LENGTH(P_ADD2);
21 BEGIN
22 IF V_LENGTH1 > 37 THEN
23 RETURN
24 F_ADD_STR
25 (
26 SUBSTR(P_ADD1, 1, V_LENGTH1 - 37),
27 NVL
28 (
29 SUBSTR
30 (
31 F_ADD_STR(SUBSTR(P_ADD1, V_LENGTH1 - 36), P_ADD2),
32 1,
33 LENGTH(F_ADD_STR(SUBSTR(P_ADD1, V_LENGTH1 - 36), P_ADD2)) - 37
34 ),
35 '0'
36 )
37 ) || SUBSTR(F_ADD_STR(SUBSTR(P_ADD1, V_LENGTH1 - 36), P_ADD2), - 37);
38 ELSIF V_LENGTH2 > 37 THEN
39 RETURN
40 F_ADD_STR
41 (
42 NVL
43 (
44 SUBSTR
45 (
46 F_ADD_STR(P_ADD1, SUBSTR(P_ADD2, V_LENGTH2 - 36)),
47 1,
48 LENGTH(F_ADD_STR(P_ADD1, SUBSTR(P_ADD2, V_LENGTH2 - 36))) - 37
49 ),
50 '0'
51 ),
52 SUBSTR(P_ADD2, 1, V_LENGTH2 - 37)
53 )
54 || SUBSTR(F_ADD_STR(P_ADD1, SUBSTR(P_ADD2, V_LENGTH2 - 36)), - 37);
55 ELSE
56 RETURN
57 LTRIM
58 (
59 TO_CHAR
60 (
61 TO_NUMBER(P_ADD1) + TO_NUMBER(P_ADD2),
62 RPAD
63 (
64 '0',
65 GREATEST(V_LENGTH1, V_LENGTH2, LENGTH(TO_NUMBER(P_ADD1) + TO_NUMBER(P_ADD2))),
66 '9'
67 )
68 )
69 );
70 END IF;
71 END;
72
73 BEGIN
74 IF V_LENGTH_OTHER_1 >= V_LENGTH_OTHER_2 THEN
75 V_RESULT := F_ADD_STR
76 (V_OTHER_STR1,
77 V_OTHER_STR2 || LPAD('0', V_LENGTH_OTHER_1 - V_LENGTH_OTHER_2, '0'));
78 ELSE
79 V_RESULT := F_ADD_STR
80 (V_OTHER_STR1 || LPAD('0', V_LENGTH_OTHER_2 - V_LENGTH_OTHER_1, '0'),
81 V_OTHER_STR2);
82 END IF;
83
84 IF LENGTH(V_RESULT) > GREATEST(V_LENGTH_OTHER_1, V_LENGTH_OTHER_2) THEN
85 RETURN NVL(LTRIM(RTRIM(
86 F_ADD_STR
87 (F_ADD_STR(V_INTEGER_STR1, V_INTEGER_STR2), 1)
88 || '.' || RTRIM(SUBSTR(V_RESULT, 2), '0'),
89 '.'), '0'), '0');
90 ELSE
91 RETURN NVL(LTRIM(RTRIM(
92 F_ADD_STR(V_INTEGER_STR1, V_INTEGER_STR2)
93 || '.' || RTRIM(V_RESULT, '0'),
94 '.'), '0'), '0');
95 END IF;
96 END;
97 /
函式已建立。
程式碼比較長,這裡就不過多的描述實現了,下面簡單看一下利用這個函式進行計算:
SQL> SELECT F_STR_ADD('12345.6789', '98.7654321') FROM DUAL;
F_STR_ADD('12345.6789','98.7654321')
------------------------------------------------------------------------------------------
12444.4443321
SQL> SELECT F_STR_ADD('5555', '12939') FROM DUAL;
F_STR_ADD('5555','12939')
------------------------------------------------------------------------------------------
18494
SQL> SELECT F_STR_ADD('0.234', '74') FROM DUAL;
F_STR_ADD('0.234','74')
------------------------------------------------------------------------------------------
74.234
SQL> SELECT F_STR_ADD('0.00001111111111111111111111111111111111111', '.234111111111111') FROM DUAL;
F_STR_ADD('0.00001111111111111111111111111111111111111','.234111111111111')
---------------------------------------------------------------------------------------
.23412222222222211111111111111111111111111
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-432940/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 利用字串實現高精度數值運算(四)字串
- 利用字串實現高精度數值運算(三)字串
- 利用字串實現高精度數值運算(二)字串
- 【Mysql學習】算術運算及字串,數值函式MySql字串函式
- 【Mysql 學習】算術運算及字串,數值函式MySql字串函式
- SHELL之數值運算
- Python基礎學習篇-2-數值運算和字串Python字串
- 利用ANTLR4實現一個簡單的四則運算計算器
- 大整數運算C#實現C#
- 計算機系統002 – 數值運算計算機
- 計算機系統002 - 數值運算計算機
- 利用版本回退實現誤運算元據恢復
- 集合-運算實現
- (位運算)兩個字串的位運算字串
- 【數值計算方法】常微分方程數值解-數值實驗
- vue中使用decimal.js對前端數值型別進行高精度計算VueDecimalJS前端型別
- 複數的四則運算(C語言實現)C語言
- C++ std::list實現大整數加法運算C++
- 刷題系列 - 實現一個指數運算方法,對遞迴次數和運算時間有約束。遞迴
- 2,javase程式碼實戰-運算子——位運算實現加密解密 (一)Java加密解密
- 字串拼接運算比較字串
- .NET的數學庫NMath實用教程——複數的值操作和邏輯運算
- 如何用位運算實現整數的加減法
- 簡單c++實現複數的四則運算C++
- excel一鍵去除公式保留文字 excel刪除公式保留運算數值Excel公式
- js如何計算一個字元在字串中出現的次數JS字元字串
- 【數值計算方法】非線性方程求根-數值實驗
- 位運算與SQL實現SQL
- 四則運算實現 (轉)
- 關於int型別數值的運算問題型別
- 高精度計算合集
- oracle中字串的大小比較,字串與數字的比較和運算Oracle字串
- javascript怎麼實現算術加法運算JavaScript
- Shell階段02 shell變數運算(整數運算/小數運算), shell變數案例變數
- SCSS 顏色值運算CSS
- 向量化實現矩陣運算最佳化(一)矩陣
- 實現四則運算的一條sql語句SQL
- 位運算實現整數與位元組陣列轉換陣列