Recent

Author Topic: Wrong place probably but 'fatal' error..  (Read 8687 times)

MorbidFractal

  • Jr. Member
  • **
  • Posts: 97
Wrong place probably but 'fatal' error..
« on: March 14, 2011, 03:30:12 pm »
Ubuntu 10.04 32 bit... Lazarus v0.9.28.2-ubuntu1 beta

Code: [Select]
procedure TDrawFrame.Paint(Sender: TObject);
var
SheetXSize: Integer;
SheetYSize: Integer;
SheetXCent: Integer;
SheetYCent: Integer;
SheetScale: Real;
SheetTRect: Trect;
X: Integer;
Y: Integer;
begin
  Case SchSheetFVar.Orientate of
  0:Case SchSheetFVar.SheetSize of
    0:begin SheetXSize:=1189;SheetYSize:=0841; end;
    1:begin SheetXSize:=0841;SheetYSize:=0594; end;
    2:begin SheetXSize:=0594;SheetYSize:=0420; end;
    3:begin SheetXSize:=0420;SheetYSize:=0297; end;
    4:begin SheetXSize:=0297;SheetYSize:=0210; end;
  end;
  1:Case SchSheetFVar.SheetSize of
    0:begin SheetYSize:=1189;SheetXSize:=0841; end;
    1:begin SheetYSize:=0841;SheetXSize:=0594; end;
    2:begin SheetYSize:=0594;SheetXSize:=0420; end;
    3:begin SheetYSize:=0420;SheetXSize:=0297; end;
    4:begin SheetYSize:=0297;SheetXSize:=0210; end;
    end;
  end;
  Output.Width  := Image1.Width;
  Output.Height := Image1.Height;
  SheetXCent    := Output.Width  div 2;
  SheetYCent    := OutPut.Height div 2;
  If Image1.Width/SheetXSize > Image1.Height/SheetYSize then
     SheetScale := (Image1.Width  - 20)/SheetXSize      else
     SheetScale := (Image1.Height - 20)/SheetYSize;
     SheetTRect := Rect(SheetXCent - SheetXSize*SheetScale div 2,
                        SheetYCent - SheetXSize*SheetScale div 2,
                        SheetXCent + SheetYSize*SheetScale div 2,
                        SheetYCent + SheetYSize*SheetScale div 2);

Fails on last line,

Code: [Select]
Trunc(SheetYCent + SheetYSize*SheetScale div 2));
with..

Quote
drawframe.pas(66,65) Error: Incompatible type for arg no. 4: Got "Real", expected "LongInt"

Which seems a bit strange given it did not moan at the prior three sums. I am expecting that although 'SheetScale' is real the div 2 would return an integer and therefore things would be OK.

So I tried,

Code: [Select]
procedure TDrawFrame.Paint(Sender: TObject);
var
SheetXSize: Integer;
SheetYSize: Integer;
SheetXCent: Integer;
SheetYCent: Integer;
SheetScale: Real;
SheetTRect: Trect;
X: Integer;
Y: Integer;
begin
  Case SchSheetFVar.Orientate of
  0:Case SchSheetFVar.SheetSize of
    0:begin SheetXSize:=1189;SheetYSize:=0841; end;
    1:begin SheetXSize:=0841;SheetYSize:=0594; end;
    2:begin SheetXSize:=0594;SheetYSize:=0420; end;
    3:begin SheetXSize:=0420;SheetYSize:=0297; end;
    4:begin SheetXSize:=0297;SheetYSize:=0210; end;
  end;
  1:Case SchSheetFVar.SheetSize of
    0:begin SheetYSize:=1189;SheetXSize:=0841; end;
    1:begin SheetYSize:=0841;SheetXSize:=0594; end;
    2:begin SheetYSize:=0594;SheetXSize:=0420; end;
    3:begin SheetYSize:=0420;SheetXSize:=0297; end;
    4:begin SheetYSize:=0297;SheetXSize:=0210; end;
    end;
  end;
  Output.Width  := Image1.Width;
  Output.Height := Image1.Height;
  SheetXCent    := Output.Width  div 2;
  SheetYCent    := OutPut.Height div 2;
  If Image1.Width/SheetXSize > Image1.Height/SheetYSize then
     SheetScale := (Image1.Width  - 20)/SheetXSize      else
     SheetScale := (Image1.Height - 20)/SheetYSize;
     SheetTRect := Rect(Trunc(SheetXCent - SheetXSize*SheetScale div 2),
                        Trunc(SheetYCent - SheetXSize*SheetScale div 2),
                        Trunc(SheetXCent + SheetYSize*SheetScale div 2),
                        Trunc(SheetYCent + SheetYSize*SheetScale div 2));

and it failed on the second to last line,

Code: [Select]
Trunc(SheetXCent + SheetYSize*SheetScale div 2),
with..

Quote
drawframe.pas(65,66) Fatal: Internal error 2009071902

??

Apparently such things are meant to be reported as bugs but I'm not sure I could explain better. Any ideas?
 

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2674
Re: Wrong place probably but 'fatal' error..
« Reply #1 on: March 14, 2011, 04:40:17 pm »
I don't see a Trunc(...) in your first source, so that you get the error "Incompatible type for arg no. 4: Got "Real", expected "LongInt"" makes sense.

The second error might be a fpc bug. Try removing drawframe.ppu and recompile.
« Last Edit: March 14, 2011, 04:44:10 pm by Marc »
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

MorbidFractal

  • Jr. Member
  • **
  • Posts: 97
Re: Wrong place probably but 'fatal' error..
« Reply #2 on: March 14, 2011, 05:06:45 pm »
Hi, Thanks for the reply.

As I said I had assumed, perhaps incorrectly, that the use of div on something containing a real would have returned an integer value and things would/should have been happy and again, in the initial example, the compiler did not complain about args 1 to 3... but fell over on arg 4.

Being a knuckle scraper I've tried other things..

Code: [Select]
procedure TDrawFrame.Paint(Sender: TObject);
var
SheetXSize: Integer;
SheetYSize: Integer;
SheetXCent: Integer;
SheetYCent: Integer;
SheetScale: Real;
XRect1Real: Real;
XRect2Real: Real;
YRect1Real: Real;
YRect2Real: Real;
XRect1:     LongInt;
XRect2:     LongInt;
YRect1:     LongInt;
YRect2:     LongInt;
SheetTRect: Trect;
X: Integer;
Y: Integer;
begin
  Case SchSheetFVar.Orientate of
  0:Case SchSheetFVar.SheetSize of
    0:begin SheetXSize:=1189;SheetYSize:=0841; end;
    1:begin SheetXSize:=0841;SheetYSize:=0594; end;
    2:begin SheetXSize:=0594;SheetYSize:=0420; end;
    3:begin SheetXSize:=0420;SheetYSize:=0297; end;
    4:begin SheetXSize:=0297;SheetYSize:=0210; end;
    end;
  1:Case SchSheetFVar.SheetSize of
    0:begin SheetYSize:=1189;SheetXSize:=0841; end;
    1:begin SheetYSize:=0841;SheetXSize:=0594; end;
    2:begin SheetYSize:=0594;SheetXSize:=0420; end;
    3:begin SheetYSize:=0420;SheetXSize:=0297; end;
    4:begin SheetYSize:=0297;SheetXSize:=0210; end;
    end;
  end;
  Output.Width  := Image1.Width;
  Output.Height := Image1.Height;
  SheetXCent    := Output.Width  div 2;
  SheetYCent    := OutPut.Height div 2;
  If Image1.Width/SheetXSize > Image1.Height/SheetYSize then
     SheetScale := (Output.Width  - 20)/SheetXSize      else
     SheetScale := (Output.Height - 20)/SheetYSize;
***  XRect1Real := SheetXCent - SheetXSize*SheetScale div 2; ***
     YRect1Real := SheetYCent - SheetYSize*SheetScale div 2;
     XRect2real := SheetXCent + SheetXSize*SheetScale div 2;
     YRect2Real := SheetYCent + SheetYSize*SheetScale div 2;
     XRect1     := Trunc(XRect1Real);
     YRect1     := Trunc(YRect1Real);
     XRect2     := Trunc(XRect2Real);
     YRect2     := Trunc(XRect2Real);
     SheetTRect := Rect(XRect1,YRect1,Xrect2,YRect2);  

The above falls over on the line with added asterisks with,

Quote
drawframe.pas(71,55) Fatal: Internal error 2009071902

I am a novice so when you ask me to 'try removing drawframe.ppu' how would I and what would be the consequences for the rest of the program or do I just ensure they do not make reference to it. You might see I don't really know much..

Oh, just in case it might be relevant DrawFrame is a TFrame....

Code: [Select]
unit drawframe;

{$mode delphi}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, ExtCtrls, Graphics;

type
  { TDrawFrame }
  TDrawFrame = class(TFrame)
    Image1: TImage;
    Output: TBitMap;
    procedure Paint(Sender: TObject);
  private
    { private declarations }
    MyObj: TObject;
  public
    { public declarations }
    constructor Create(TheOwner: TComponent); override;
    destructor Destroy; override;
  end;    

and I do get a compiler warning,

Quote
drawframe.pas(15,15) Warning: An inherited method is hidden by "TDrawFrame.Paint(TObject);"

Thanks again.

Edit

Oh, from your sig..

Quote
//-Bugs reported on the forum will be forgotten. Use the bug tracker.

If it is a bug I don't mind following it through via the 'bug tracker'. Unfortunately you may find I am not the most 'focussed' of people so I might give too much irrelevant information.

« Last Edit: March 14, 2011, 05:15:07 pm by MorbidFractal »

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2674
Re: Wrong place probably but 'fatal' error..
« Reply #3 on: March 14, 2011, 06:20:39 pm »
Now I noticed:

Quote
Code: Pascal  [Select][+][-]
  1. ..
  2. XRect1Real := SheetXCent - SheetXSize*SheetScale div 2;
  3. ..

Div can only be used for integer divisions. Since SheetScale is a float, SheetXSize*SheetScale is a float.
So use / instead of  div

Code: Pascal  [Select][+][-]
  1. ..
  2. XRect1Real := SheetXCent - SheetXSize*SheetScale / 2;
  3. ..


BTW, imo better use Double instead of Real type. Reals are (or were) a non native 6 byte floatingpoint number, where Double is native
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

MorbidFractal

  • Jr. Member
  • **
  • Posts: 97
Re: Wrong place probably but 'fatal' error..
« Reply #4 on: March 14, 2011, 11:11:44 pm »
Aha!....

http://wiki.lazarus.freepascal.org/Div

Quote
Div is division in which the fractional part (remainder) is discarded. It mean the integer part of the result of dividing two integers.

That will be, as usual, my mistake then. Misconception or Preconception..Not reading the Manual.

Just put your suggestion in and it compiles. Whether the result will look right when it finally gets drawn is another matter. Obviously I'll just hack about until it works.  

:-[

Onwards!! and thank you very much again.

Plus for the note about Double as Opposed to Real..
« Last Edit: March 14, 2011, 11:13:36 pm by MorbidFractal »

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Wrong place probably but 'fatal' error..
« Reply #5 on: March 14, 2011, 11:45:57 pm »
Here (fpc x86_64 and {$mode objfpc} )

sizeof(real)=8

and

sizeof(real48)=6  // this is what Marc mean

I think it depends on compiler mode and architecture what 'real' really is. Real48 is TurboPascal heritage.
I also prefer Single, Double or Extended because one knows what it really is.
« Last Edit: March 14, 2011, 11:56:27 pm by Blaazen »
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Zoran

  • Hero Member
  • *****
  • Posts: 1988
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Wrong place probably but 'fatal' error..
« Reply #6 on: March 15, 2011, 12:02:06 am »

Just put your suggestion in and it compiles. Whether the result will look right when it finally gets drawn is another matter. Obviously I'll just hack about until it works.  

:-[

If you need a whole number as a result, you can use Trunc or Int functions.

The only difference between these two is the result type. When operating on Doubles, Int returns Double and Trunc returns Integer. For example:
Code: [Select]
...
X, Y, Z: Double;
N: Integer;
...
X := 8.0;
Y := 3.0;

Z := Int(X / Y); // now, Z is 2.0
N := Trunc(X / Y); // now N is 2

// you can notice that...
Z := Trunc(X / Y);
// will also set Z to 2.0, due to implicit cast. I beleive that it would be slower, though.

Also see these functions:
Round
Frac
Floor
Ceil
Swan, ZX Spectrum emulator https://github.com/zoran-vucenovic/swan

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2674
Re: Wrong place probably but 'fatal' error..
« Reply #7 on: March 15, 2011, 11:42:21 am »
Here (fpc x86_64 and {$mode objfpc} )

sizeof(real)=8

and

sizeof(real48)=6  // this is what Marc mean

I think it depends on compiler mode and architecture what 'real' really is. Real48 is TurboPascal heritage.
I also prefer Single, Double or Extended because one knows what it really is.

SizeOf(Extended) is also unknown, iirc it is only supported native on x86, on all other platforms extended = double
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

MorbidFractal

  • Jr. Member
  • **
  • Posts: 97
Re: Wrong place probably but 'fatal' error..
« Reply #8 on: March 15, 2011, 12:02:09 pm »
OK.. Thanks for the help and the extra information. Single and double it will be then. At my level it might make sense in terms of efficiency of memory usage versus precision versus processing overheads.

6 bytes would seem to something that does not 'pack' on a 32 bit system since it would span two locations.. may as well use the full 8.

Of course I am just rambling.

Edit

Oh... All working as well, or at least that bit...

 :)
« Last Edit: March 15, 2011, 02:57:22 pm by MorbidFractal »

 

TinyPortal © 2005-2018