2012-06-10 3 views
8

델파이를 엑셀처럼 라운드로 만들려고하고 있지만 할 수 없습니다. 내가 54321.245로 설정되어 통화 변수를 사용하고 있습니다 때 나는 그것이 은행 반올림을 사용하여 반올림이 변수의 형식을Delphi 통화 유형을 Excel과 같은 원형으로 항상 얻으려면 어떻게해야합니까?

procedure TForm1.Button1Click(Sender: TObject); 
var 
s : string; 
c : currency; 
begin 
c := 54321.245; 
s := ''; 
s := s + Format('Variable: %m',[c]); 
s := s + chr(13); 
s := s + Format(' Literal: %m',[54321.245]); 
ShowMessage(s); 
end; 

Delphi Rounding

: 여기에 코드입니다. 그러나 리터럴과 동일한 값을 포맷하면 Excel이 반올림하는 방식이 반올림됩니다.

나는 통화 변수 또는 리터럴 값을 형성하는지에 관계없이 $ 54,321.25으로 반올림 할 것으로 예상했다. Delphi가 매번 Excel과 같은 방식으로 반올림되도록하려면 어떻게해야합니까?

난 단지 델파이 마는 여러 가지 방법을 보여 리터럴을 사용하고

The rounding I expect to see is as follows: 
54,321.245 = 54,321.25 
54,321.2449 = 54,321.24 
54,431.2499 = 54,421.25 

편집. 나는 실제 코드에서 변수를 사용할 것으로 기대한다.

참고 : 나는을 확장통화에서 변수를 변경하면
가 제대로 라운드

편집 # 2

일부는 내가이없는 것을 제안했다

내 요구 사항에 대한 명확한 이해는 절대적으로 사실이 아닙니다. 나는 나의 요구 사항에 대한 아주 명확한 이해를 가지고있다. 나는 분명히 그것들을 설명하는 훌륭한 일을하지 않는다. 내가 원하는 반올림 방법은 소수 둘째 자리입니다. deimal 부분의 1000 번째 값이 0.005 이상일 때 0.01로 반올림하고 싶습니다. Delphi에서 제공하는 통화 유형이 이것을 수행하지 않습니다. 필자는 또한 델파이의 통화와 같다고 가정 한 돈 데이터 유형으로 Microsoft SQL을 사용하여이 예제를 시도했으며 SQL은 내가 설명한 방식으로 돈을 버립니다.

  • SQL 돈> = 0.005 = 0.01
  • 델파이 환율> = 0.005 = 0.00

편집 # 3
좋은 기사 : http://rvelthuis.de/articles/articles-floats.html
가능한 해결 방법 : http://rvelthuis.de/programs/decimals.html

편집 # 4
다음은 엠바 카데로 토론의 솔루션 중 하나입니다

function RoundCurrency(const Value: Currency): Currency; 
var 
    V64: Int64 absolute Result; 
    Decimals: Integer; 
begin 
    Result := Value; 
    Decimals := V64 mod 100; 
    Dec(V64, Decimals); 
    case Decimals of 
    -99 .. -50 : Dec(V64, 100); 
    50 .. 99 : Inc(V64, 100); 
    end; 
end;
+1

당신은 엑셀의 모든 API와 기능을 통해 반올림에서 100 % 일치하는지 확인 있습니까? –

+0

@Warren - 아니요, 100 % 확실하지 않습니다. 금융 응용 프로그램을 판매하며 Excel에서 제시 한 수치와 일치하는지 확인해야합니다. –

+2

이 질문에 올바로 대답하려면 실제로 어떤 종류의 반올림을해야하는지 알려줄 필요가 있습니다. –

답변

12

, 당신이 찾고 있습니다 :

function RoundTo2dp(Value: Currency): Currency; 
begin 
    Result := Trunc(Value*100+IfThen(Value>0, 0.5, -0.5))/100; 
end; 
+0

지금까지 읽은 것만 큼 통화 처리를 권장하지 않을 때 FPU를 사용할 수 있습니다. 반올림 문제를 추적하기가 어렵습니다. 이 문제를 피하거나 큰주의를 기울여 해결할 수있는 해결책이 있습니다. –

+1

+1 멋지게 ... 당신은 다른 행성 다비드 출신입니다. –

+0

@SertacAkyuz 무엇을 운전하고 있습니까? 화폐 계산은 FPU를 사용합니다. –

0

당신은에 의해 어떻게 델파이 반올림 숫자에 대한 제어를 얻을 수 있습니다 : rmNearest을 사용하여 불행하게도

uses Math; 
... 

procedure TForm1.Button1Click(Sender: TObject); 
var 
s : string; 
c : currency; 
begin 
SetRoundMode(rmNearest); 

c := 54321.245; 
s := ''; 
s := s + Format('Variable: %m',[c]); 
s := s + chr(13); 
s := s + Format(' Literal: %m',[54321.245]); 
ShowMessage(s); 
end; 

는, 델파이는 수 54321.245는 54321.24에 가까운 결정 54321.25보다

+0

그건 사실이 아닙니다. c : = 54321.244의 값을 변경하면 $ 54,321.45로 형식화되고 $ 54,321.44가되어야합니다 (간단합니다). 통화 대신 확장 된 유형을 사용하면이 문제를 해결할 수 있습니다. –

+0

사과, @CapeCodGunny. 위의 내용을 편집했습니다 – Hendra

+0

사과하지 마십시오. 우리는 모두 배우고 있습니다. 통화 유형이 확장 유형과 같이 둥글거나 형식을 지정하지 않는 것으로 보입니다. Delphis의 Math 단위 내부에서 재정 함수 중 몇 가지를 살펴 보았습니다. 그 중 하나는 통화 유형을 사용하지 않았습니다. 그들은 모두 확장 된 유형을 사용합니다. 그래서 델파이의 수학 단위에서 작동한다면 그것은 저에게 효과적입니다. :-) –

6

원하는 방식으로 RTL을 만들 수 없습니다.델파이에서 반올림에 영향을 미치는 방법은 반올림을 위해 sets the FPU conrol wordsets the FPU conrol word을 사용하는 것입니다. 그러나 내가 말할 수있는 한 정확히 그 중간을 반올림하기위한 FPU 지원은 없습니다 (이는 일반적으로 피할 수 있습니다. 높은 값).

사용자 고유의 반올림 기능을 구현해야합니다. Embarcadero 포럼의 Delphi Rounding thread에는 여러 가지 해결책이 포함되어 있습니다. 내가 제대로 이해하면

+0

이것은 내가 찾고있는 것입니다. 고맙습니다. –

관련 문제