Subject Re: [IBO] Re: Urgent! Invalid Type Cast
Author Martijn Tonies
Please be SPECIFIC with your info! Have you ever had co-workers
coming up to you saying "it doesn't work" and then expecting you to
answer that?

Now, where exactly does this code fail to compile.

> function Int64ToCurrency( AVal: ISC_INT64; AScale: smallint ): currency;
> {$IFNDEF IBO_VCL35}
> var
> i: smallint;
> AFactor: ISC_INT64;
> {$ENDIF}
> begin
> {$IFDEF IBO_VCL35}
> raise Exception.Create( 'Unsupported' );
> {$ELSE}
> // Do not apply rounding - used for reading data as stored in database.
> // Originally I was starting by casting AVal to Result and then scaling
> // the currency Result variable. This resulted in rounding
> problems. It
> // seems that some Delphi maths functions involving currency use
> extended
> // for interim values with subsequent problems at the limits of the
> range.
> // So now I manipulate the int64 value first, and then assign the final
> // value directly to Result. This direct cast produces an implicit
> scale
> // of 4 (the fixed integer scale of the currency data type), and so the
> // actual scaling value must be adjusted as follows. This adjustment
> // avoids overflowing the currency value when scaling adjustment
> will make
> // the integer value fit. There is still a limit (14 integer
> digits), but
> // this should ensure we accept all possible values within the limit.
> AScale := AScale + 4;
> if (AScale <> 0) and (AVal <> 0) then
> begin
> AFactor := 1;
> for i := 1 to abs(AScale) do
> AFactor := AFactor * 10;
> if AScale > 0 then // increasing scale
> begin
> {$IFDEF IBO_VCL40_OR_GREATER}
> if (AVal > (High(ISC_INT64) div AFactor)) or
> (AVal < (Low (ISC_INT64) div AFactor)) then
> raise Exception.Create( E_Int64Overflow );
> {$ENDIF}
> AVal := AVal * AFactor;
> end
> else // decreasing scale
> begin
> {$IFDEF IBO_VCL40_OR_GREATER}
> AVal := AVal div AFactor;
> {$ELSE}
> AVal := AVal / AFactor;
> {$ENDIF}
> end;
> end;
> Result := currency((@AVal)^);
> {$ENDIF}
> end;
>
>
> function CurrencyToInt64( AVal: currency; AScale: smallint ): ISC_INT64;
> {$IFNDEF IBO_VCL35}
> var
> i: smallint;
> AFactor: ISC_INT64;
> {$IFDEF IBO_VCL40_OR_GREATER}
> tmpMod,
> tmpHalf: ISC_INT64;
> {$ENDIF}
> {$ENDIF}
> begin
> {$IFDEF IBO_VCL35}
> raise Exception.Create( 'Unsupported' );
> {$ELSE}
> // See notes for Int64ToCurrency for explanation of this code.
> Result := ISC_INT64((@AVal)^);
> AScale := AScale - 4;
> if (AScale <> 0) and (Result <> 0) then
> begin
> AFactor := 1;
> for i := 1 to abs(AScale) do
> AFactor := AFactor * 10;
> if AScale > 0 then // increasing scale
> begin
> {$IFDEF IBO_VCL40_OR_GREATER}
> if (Result > (High(ISC_INT64) div AFactor)) or
> (Result < (Low(ISC_INT64) div AFactor)) then
> raise Exception.Create( E_Int64Overflow );
> {$ENDIF}
> Result := Result * AFactor;
> end
> else // decreasing scale
> begin
> {$IFDEF IBO_VCL40_OR_GREATER}
> // Need to calculate the rounding adjustments required for
> statistical
> // rounding. Probably should setup asm stuff for this but lets
> see how
> // we go without for the moment.
> tmpMod := Result mod AFactor;
> tmpHalf := (AFactor div 2);
> Result := Result div AFactor;
> // more than half remainder goes up (down if negative)
> // exactly half remainder goes up (down if negative) only when
> // the result is odd (even results dont need adjustment)
> if (abs(tmpMod) > tmpHalf) or
> ((abs(tmpMod) = tmpHalf) and ((Result mod 2) = 1)) then
> begin
> if Result < 0 then
> Dec(Result,1)
> else
> Inc(Result,1);
> end;
> {$ELSE}
> // Sorry Delphi3 people but I will not write
> // rounding for a system that I cannot check.
> Result := Result / AFactor;
> {$ENDIF}
> end;
> end;
> {$ENDIF}
> end;
>
>
>
> --- In IBObjects@yahoogroups.com, "Martijn Tonies" <m.tonies@...> wrote:
> >
> >
> >
> > > I don't have much information to give thats the problem.
> >
> > Care to post the code at and around those lines?
> >
> > > I am trying to install a design time package which contains 2 pas
> > > files to register the components and properties.
> > >
> > > When I build it, D2007 throws this:
> > >
> > > [DCC Error] IB_Utils.pas(1455): E2089 Invalid typecast
> > > [DCC Error] IB_Utils.pas(1591): E2089 Invalid typecast
> > > [DCC Error] IB_Session.pas(824): F2063 Could not compile used unit
> > > 'IB_Utils.pas'

Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com