Recent

Author Topic: How to force the not operator to return a byte  (Read 13469 times)

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: How to force the not operator to return a byte
« Reply #30 on: May 15, 2021, 11:35:21 pm »
RTFM!

Siezof returns the size of variables. Simple as well as records.

And if do a sizeof(SomePointer) it return the size of the pointer.

That's why it is called sizeof.

Winni

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: How to force the not operator to return a byte
« Reply #31 on: May 15, 2021, 11:55:57 pm »
Great information, Winni!!

Are you suggesting a bug in SizeOf or its documentation?

alpine

  • Hero Member
  • *****
  • Posts: 1038
Re: How to force the not operator to return a byte
« Reply #32 on: May 16, 2021, 12:32:28 am »
*snip*

How about you do the correct test!
Code: Pascal  [Select][+][-]
  1. const
  2.   b=1;
  3.  
  4. begin
  5.   WriteLn(SizeOf(b));
  6.   WriteLn(SizeOf(NOT b));
  7. //OR
  8.   WriteLn(SizeOf(1));
  9.   WriteLn(SizeOf(NOT 1));

Constants, remember? Ordinal constants.

I see. But you wrote:
Code: Pascal  [Select][+][-]
  1. SizeOf(NOT SomeValue) equals SizeOf(PtrInt)

 It's a sloppy writing.

And why
Code: Pascal  [Select][+][-]
  1. $FF xor B
should be treated differently than
Code: Pascal  [Select][+][-]
  1. not B
?

Hopefully you see the reason now.

Actually, no. May be you're hopeful that I can differentiate between (128 or 64) and $FF but I can't. Both:
Code: [Select]
not (128 or 64) and
Code: [Select]
$FF xor (128 or 64) are non-terminal <expr> on terminals $FF, 128, 64 (all fit in a byte, i.e. 0..2^8-1) and I can't see the reason the former will be widened to PtrInt and the latter -not.
Nowhere I can see a type hint to the compiler as it would be if they're declared as variables (e.g. V: Type).
Why the widening rules for not and xor would differ?


 
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: How to force the not operator to return a byte
« Reply #33 on: May 16, 2021, 12:34:01 am »
Hi !

I have read the sizeof documentation of UCSD Pascal 40 yers ago.Since then has not much changed.

Winni


winni

  • Hero Member
  • *****
  • Posts: 3197
Re: How to force the not operator to return a byte
« Reply #34 on: May 16, 2021, 01:02:04 am »
Hi!

Perhaps one usefull tip:

If you use NOT without any type casting, the result is in the native size of your machine:

On 32Bit machines it is 4 bytes
On 64Bit machines it is 8 bytes

It does not matter if the input is a byte, a word or an integer.

Winni


engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: How to force the not operator to return a byte
« Reply #35 on: May 16, 2021, 01:10:58 am »
*snip*

How about you do the correct test!
Code: Pascal  [Select][+][-]
  1. const
  2.   b=1;
  3.  
  4. begin
  5.   WriteLn(SizeOf(b));
  6.   WriteLn(SizeOf(NOT b));
  7. //OR
  8.   WriteLn(SizeOf(1));
  9.   WriteLn(SizeOf(NOT 1));

Constants, remember? Ordinal constants.

I see.

I thought that meant we are done!!

But you wrote:
Code: Pascal  [Select][+][-]
  1. SizeOf(NOT SomeValue) equals SizeOf(PtrInt)

 It's a sloppy writing.

Why do think it is sloppy? How do you prefer I write it?


And why
Code: Pascal  [Select][+][-]
  1. $FF xor B
should be treated differently than
Code: Pascal  [Select][+][-]
  1. not B
?

Hopefully you see the reason now.

Actually, no. May be you're hopeful that I can differentiate between (128 or 64) and $FF but I can't. Both:
Code: [Select]
not (128 or 64) and
Code: [Select]
$FF xor (128 or 64) are non-terminal <expr> on terminals $FF, 128, 64 (all fit in a byte, i.e. 0..2^8-1) and I can't see the reason the former will be widened to PtrInt and the latter -not.
Nowhere I can see a type hint to the compiler as it would be if they're declared as variables (e.g. V: Type).
Why the widening rules for not and xor would differ?

I don't have a Delphi. Do you have [access to] a recent version of Delphi?
If Delphi widens the result of NOT, FPC is going to follow for compatibility. Otherwise it is a bug.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: How to force the not operator to return a byte
« Reply #36 on: May 16, 2021, 01:13:06 am »
Hi!

Perhaps one usefull tip:

If you use NOT without any type casting, the result is in the native size of your machine:

On 32Bit machines it is 4 bytes
On 64Bit machines it is 8 bytes

It does not matter if the input is a byte, a word or an integer.

Winni

Yes, Winni, that is correct. Is it documented? How about Delphi?

alpine

  • Hero Member
  • *****
  • Posts: 1038
Re: How to force the not operator to return a byte
« Reply #37 on: May 16, 2021, 01:20:40 am »
Hi !

I have read the sizeof documentation of UCSD Pascal 40 yers ago.Since then has not much changed.

Winni
+1 for mentioning UCSD Pascal.

I doubt it has SizeOf, it is a C/C++ operator and should return the actual storage size of a variable or a type. As long it is used over a constant, which should be substituted as a literal, (@engkin) it can be considered as a bug.

IMHO,
Quote
If Delphi widens the result of NOT, FPC is going to follow for compatibility. Otherwise it is a bug.
is not an excuse.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: How to force the not operator to return a byte
« Reply #38 on: May 16, 2021, 01:31:29 am »
(@engkin) it can be considered as a bug.

The OP made it clear that it changed after FPC 3.0.4.
Mark PMed PascalDragon, but we did not see his response.
Without comparing it with Delphi I cannot be sure if it is a bug or a feature.
Since you are that sure, maybe you can file a bug report.
« Last Edit: May 16, 2021, 01:35:35 am by engkin »

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: How to force the not operator to return a byte
« Reply #39 on: May 16, 2021, 01:33:28 am »
Hi!

As I said:

If you repair a Delphi bug in Lazarus, it is considered to be a bug, because it is not Delphi compatible.

That's the way to bring people in the madhouse.

Winni

alpine

  • Hero Member
  • *****
  • Posts: 1038
Re: How to force the not operator to return a byte
« Reply #40 on: May 16, 2021, 01:47:45 am »
*snip*
Since you are that sure, maybe you can file a bug report.
I'd rather not use sizeof that way.
What bothers me more is the different interpretations of the otherwise identical bitwise not and xor
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: How to force the not operator to return a byte
« Reply #41 on: May 16, 2021, 02:36:22 am »
*snip*
Since you are that sure, maybe you can file a bug report.
I'd rather not use sizeof that way.
What bothers me more is the different interpretations of the otherwise identical bitwise not and xor

Just to be clear, when I mentioned the bug report I was talking about NOT.

BobDog

  • Sr. Member
  • ****
  • Posts: 394
Re: How to force the not operator to return a byte
« Reply #42 on: May 16, 2021, 11:20:44 am »

Getting all tied up here, that's for sure.
Code: Pascal  [Select][+][-]
  1.  
  2. {$MACRO ON}
  3.  {$define c:= knot(a or b) }
  4.  
  5.  const
  6.  a=128;
  7.  b=64;
  8.  
  9.   function knot(i:integer):byte;
  10.   begin
  11.   exit(not i);
  12.   end;
  13.  
  14. begin
  15. writeln(c);
  16. writeln;
  17. readln;
  18. end.

tetrastes

  • Sr. Member
  • ****
  • Posts: 473
Re: How to force the not operator to return a byte
« Reply #43 on: May 16, 2021, 12:28:03 pm »
What bothers me more is the different interpretations of the otherwise identical bitwise not and xor

It seems that you do not understand the difference between byte variables and ordinary constants. Then consider them as integers.  :D
And maybe the output of this code will help you.
Code: Pascal  [Select][+][-]
  1. const
  2.   a = 128;
  3.   b = 64;
  4.   c = not (a or b);
  5.   d = $FF xor (a or b);
  6.  
  7. var
  8.   ba : byte = 128;
  9.   bb : byte = 64;
  10.   bc, bd : byte;
  11.  
  12.   ia : integer = 128;
  13.   ib : integer = 64;
  14.   ic, id : integer;
  15.  
  16. begin
  17.   writeln('constants');
  18.   writeln(c);
  19.   writeln(d);
  20.   writeln;
  21.  
  22.   bc := not (ba or bb);
  23.   bd := $FF xor (ba or bb);
  24.   writeln('bytes');
  25.   writeln(bc);
  26.   writeln(bd);
  27.   writeln;
  28.  
  29.   writeln('integers');
  30.   ic := not (ia or ib);
  31.   id := $FF xor (ia or ib);
  32.   writeln(ic);
  33.   writeln(id);
  34.   readln;
  35. end.  

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: How to force the not operator to return a byte
« Reply #44 on: May 16, 2021, 12:51:05 pm »
Not(constant) does something different then is assumed xor does not suffer from this negation 'error'.

Code: Pascal  [Select][+][-]
  1. program test;
  2.  
  3. {$MODE OBJFPC}
  4.  
  5. (*
  6. https://freepascal.org/docs-html/ref/refsu4.html#x26-250003.1.1
  7.  
  8. With the exception of floating point value types, all base types
  9. are ordinal types.
  10.  
  11. A list of predefined integer types is presented in table (3.1).
  12.  
  13. Remark: The compiler decides on the type of an integer constant
  14. based on the value: An integer constant gets the smallest possible
  15. signed type. The first match in table (3.3) is used.
  16.  
  17. That means constants in the range -128..127 are mapped to shortint,
  18. constants in range 128..255 are mapped to byte, etc.
  19. Constants in the range 2147483647..high(cardinal) are parsed as
  20. cardinals, and all decimal constants which do not fit either of
  21. the above ranges are parsed as 64-bit integer constants.
  22.  
  23. As a pascal compiler, Free Pascal does automatic type conversion and
  24. upgrading in expressions where different kinds of integer types are
  25. used:
  26. 1 Every platform has a “native” integer size, depending on whether
  27.   the platform is 8-bit, 16-bit, 32-bit or 64-bit. E. g. on AVR this
  28.   is 8-bit.
  29. 2 Every integer smaller than the “native” size is promoted to a
  30.   signed version of the “native” size. Integers equal to the “native”
  31.   size keep their signedness.
  32. 3 The result of binary arithmetic operators (+, -, *, etc.) is
  33.   determined in the following way:
  34.   a If at least one of the operands is larger than the native integer
  35.     size, the result is chosen to be the smallest type that encompasses
  36.     the ranges of the types of both operands. This means that mixing an
  37.     unsigned with a smaller or equal in size signed will produce a
  38.     signed type that is larger than both of them.
  39.   b If both operands have the same signedness, the result is the same
  40.     type as them. The only exception is subtracting (-): in the case of
  41.     unsigned - unsigned subtracting produces a signed result in FPC
  42.     (as in Delphi, but not in TP7).
  43.   c Mixing signed and unsigned operands of the “native” int size
  44.     produces a larger signed result. This means that mixing longint and
  45.     longword on 32-bit platforms will produce an int64. Similarly,
  46.     mixing byte and shortint on 8-bit platforms (AVR) will produce
  47.     a smallint.
  48. *)
  49.  
  50. begin
  51.   WriteLn(64);
  52.   WriteLn(SizeOf(64));
  53.   WriteLn(128);
  54.   WriteLn(SizeOf(128));
  55.   WriteLn(128 or 64);
  56.   WriteLn(SizeOf(128 or 64));
  57.   WriteLn(not(128 or 64));
  58.   WriteLn(SizeOf(not(128 or 64)));
  59. end.
  60.  
  61. (*
  62.   64
  63.   1
  64.   128
  65.   1
  66.   192
  67.   1
  68.   -193
  69.   8
  70. *)
  71.  
  72.  

It's written in the documentation. It requires to read those line that apply for this situation  ;)

 

TinyPortal © 2005-2018