숫자를 세 부분으로 나누고 그 총합을 원래의 숫자와 일치시키는 알고리즘이 있습니까?
예를 들어 다음 예제를 고려할 경우.
100.00 - Original Number
33.33 - 1st divided by 3
33.33 - 2nd divided by 3
33.33 - 3rd divided by 3
99.99 - Is the sum of the 3 division outcomes
But i want it to match the original 100.00
제가 볼 수 있었던 한 가지 방법은 원래의 숫자에서 처음 두 분할을 뺀 것이었고 그 결과는 제 세 번째 숫자가 될 것입니다.이제 그 3개의 번호를 찍으면 원래 번호를 받습니다.
100.00 - Original Number
33.33 - 1st divided by 3
33.33 - 2nd divided by 3
33.34 - 3rd number
100.00 - Which gives me my original number correctly. (33.33+33.33+33.34 = 100.00)
Oracle PL/SQL이나 구현 가능한 함수 등에서 이에 대한 공식이 있습니까?
미리 감사드립니다!
이 버전은 정밀도를 매개변수로 사용합니다.
with q as (select 100 as val, 3 as parts, 2 as prec from dual)
select rownum as no
,case when rownum = parts
then val - round(val / parts, prec) * (parts - 1)
else round(val / parts, prec)
end v
from q
connect by level <= parts
no v
=== =====
1 33.33
2 33.33
3 33.34
예를 들어 현재 월의 일 수에 값을 분할하려면 다음 작업을 수행할 수 있습니다.
with q as (select 100 as val
,extract(day from last_day(sysdate)) as parts
,2 as prec from dual)
select rownum as no
,case when rownum = parts
then val - round(val / parts, prec) * (parts - 1)
else round(val / parts, prec)
end v
from q
connect by level <= parts;
1 3.33
2 3.33
3 3.33
4 3.33
...
27 3.33
28 3.33
29 3.33
30 3.43
각 월 간에 값을 할당하려면 대신 이 작업을 수행할 수 있습니다(변경).level <= 3
계산된 개월 수를 변경하는 방법):
with q as (
select add_months(date '2013-07-01', rownum-1) the_month
,extract(day from last_day(add_months(date '2013-07-01', rownum-1)))
as days_in_month
,100 as val
,2 as prec
from dual
connect by level <= 3)
,q2 as (
select the_month, val, prec
,round(val * days_in_month
/ sum(days_in_month) over (), prec)
as apportioned
,row_number() over (order by the_month desc)
as reverse_rn
from q)
select the_month
,case when reverse_rn = 1
then val - sum(apportioned) over (order by the_month
rows between unbounded preceding and 1 preceding)
else apportioned
end as portion
from q2;
01/JUL/13 33.7
01/AUG/13 33.7
01/SEP/13 32.6
유리수를 사용합니다.단순 값이 아닌 분수로 숫자를 저장할 수 있습니다.그렇게 해야 수량이 3으로 나뉘고 원래 수량과 합이 된다는 것을 확인할 수 있습니다.물론 라운딩과 남은 음식들을 가지고도 무리한 일을 할 수 있습니다. 정확히 3분으로 나누지 않아도 상관없다면 말입니다.
"알고리즘"은 단순히
100/3 + 100/3 + 100/3 == 300/3 == 100
분자와 분모를 모두 별도의 필드에 저장한 다음 분자를 추가합니다.값을 표시할 때 항상 부동 소수점으로 변환할 수 있습니다.
Oracle 문서에는 다음과 같은 구현 방법에 대한 좋은 예도 있습니다.
CREATE TYPE rational_type AS OBJECT
( numerator INTEGER,
denominator INTEGER,
MAP MEMBER FUNCTION rat_to_real RETURN REAL,
MEMBER PROCEDURE normalize,
MEMBER FUNCTION plus (x rational_type)
RETURN rational_type);
다음은 매개 변수화된 SQL 버전입니다.
SELECT COUNT (*), grp
FROM (WITH input AS (SELECT 100 p_number, 3 p_buckets FROM DUAL),
data
AS ( SELECT LEVEL id, (p_number / p_buckets) group_size
FROM input
CONNECT BY LEVEL <= p_number)
SELECT id, CEIL (ROW_NUMBER () OVER (ORDER BY id) / group_size) grp
FROM data)
GROUP BY grp
출력:
COUNT(*) GRP
33 1
33 2
34 3
입력 파라미터(p_number 및 p_buckets)를 편집하면 SQL은 기본적으로 요청된 버킷 수(p_buckets)에 p_number를 최대한 균등하게 분배합니다.
어제 시작번호에서 3개 중 2개를 빼고 100 - 33.33 - 33.33 = 33.34로 이 문제를 해결했는데 합산한 결과는 여전히 100입니다.
언급URL : https://stackoverflow.com/questions/22026226/is-there-an-algorithm-that-can-divide-a-number-into-three-parts-and-have-their-t
'source' 카테고리의 다른 글
루트(또는 sudo)에서 NVM을 사용할 수 없습니다. (0) | 2023.11.07 |
---|---|
문자열에 C#의 숫자만 포함되어 있는지 확인하는 가장 빠른 방법 (0) | 2023.11.02 |
리눅스에서 syscall 기능을 다시 구현(또는 랩)하려면 어떻게 해야 합니까? (0) | 2023.11.02 |
XML 파일을 어떻게 구문 분석합니까? (0) | 2023.11.02 |
레일, link_to helper 클릭 후 자바스크립트가 로딩되지 않음 (0) | 2023.11.02 |