Jump to content

dummzeuch

Members
  • Content Count

    2634
  • Joined

  • Last visited

  • Days Won

    91

Everything posted by dummzeuch

  1. dummzeuch

    converting float to text

    Turns out I didn't check carefully enough. There actually are values in that array that are much too large, and these values show up in the Delphi dump as well. So: There was nothing wrong with the C++ code, just me being stupid. Sorry about that. I still have no idea where these values come from. Maybe the algorithm that calculates them is flawed.
  2. I had some curious bug today with the following code: procedure ReadHeader(out _w, _h, _Depth: Integer); const PGM_Magic_Number = 'P5'; var s: string; begin s := ReadChar + ReadChar; if s <> PGM_Magic_Number then raise ESigError.Create(_('File is not a valid PGM file:') + ' ' + _fn); // more code here end; Which failed the test even though the first call to ReadChar returns 'P' and the second returns '5' (I stepped through it in the debugger) so s should have been 'P5', but the actual value of s was '5P'. Apparently Delphi created code that called the second ReadChar before the first. But why? Maybe because it fills the parameters for the function System._UStrCat3, that it apparently calls to do the concatenation, from right to left? So I changed the code like this: procedure ReadHeader(out _w, _h, _Depth: Integer); const PGM_Magic_Number = 'P5'; var s: string; begin s := ReadChar; s := s + ReadChar; if s <> PGM_Magic_Number then raise ESigError.Create(_('File is not a valid PGM file:') + ' ' + _fn); // more code here end; and it works now.
  3. Now that you mention it: There was some Unicode stuff involved somewhere else in the unit (type casts from AnsiChar to Char), so it can't have been Delphi 2007 ... Must have been Delphi 10.2 then. (Sorry, I have been trying to get somebody competent at Deutsche Telekom on the phone for the last 2 hours. This is getting on my nerves and wreaking havoc with my concentration.)
  4. No idea. Maybe we are using different Delphi versions (mine is Delphi 2007 in this case) or compiler settings (trying to compare those would open a can of worms).
  5. Does anybody know about (preferably free) Delphi code for reading a .ply (Polygon) file? I'm most interested in the binary format but if the code can also handle the text format that would be a plus. I'm about to write this myself but I don't want to reinvent the wheel.
  6. Wikipedia says otherwise: https://en.wikipedia.org/wiki/PLY_(file_format) "There are two versions of the file format, one in ASCII, the other in binary."
  7. Sorry for the confusion, I got distracted when I wrote that post. That source code was just for showing that ReadChar2 is called first. I have now added an explanation to that post.
  8. A simple test case would be this: function ReadChar1: Char: begin Result := 'P'; end; function ReadChar2: Char: begin Result := '5'; end; procedure ReadHeader(out _w, _h, _Depth: Integer); const PGM_Magic_Number = 'P5'; var s: string; begin s := ReadChar1 + ReadChar2; if s <> PGM_Magic_Number then raise ESigError.Create(_('File is not a valid PGM file:') + ' ' + _fn); // more code here end; Edit: I forgot to add for what this is a test case. It's for stepping through with the debugger. Since ReadChar1 and ReadChar2 are two different functions, it's clear in which order they are executed. It's ReadChar2 first and ReadChar1 second.
  9. This looks promising: https://sourceforge.net/p/glscene/code/HEAD/tree/trunk/Source/GLS.FilePLY.pas Thanks Edit: This seems to only read PLY files in text format.
  10. You could simply use Notepad++ to change the line break to Unix and back to Windows. That fixes any of these problems. Also Delphi 11 comes with a setting to do that automatically: Tools -> Options -> User Interface -> Editor -> Line Endings: "Convert files with known extensions to CRLF" (No idea when that was introduced. I had not noticed before. Also no idea whether it actually works.)
  11. They will just introduce a new API and deprecate the old one. Happened before, will happen again.
  12. There are usually some tasks that do not need to run on the performance cores, so setting the affinity mask for the whole program may not be the best strategy, even though it's the easiest way. But I'm sure that sooner or later Windows will start ignoring those masks because everybody sets them. Of course this is currently the only way to do that for threads generated using parallel for.
  13. I have inherited this code from a program originally written in Borland Pascal for DOS, which I have adapted to Delphi 32 Bit: function BuildDigits(_Digits: UInt16; _Invalids: UInt8): UInt16; var TempInt: Int16; begin TempInt := _Digits; Dec(TempInt, 2048); TempInt := TempInt * 11; TempInt := (TempInt and $FFFC) or (_Invalids and $03); // <-- crashes here TempInt := Swap16(TempInt); Move(TempInt, Result, SizeOf(Result)); end; The adaptations were to change variable declarations: Word -> UInt16, Byte -> UInt8, Integer -> Int16 (Integer was 16 bits in Borland Pascal). Only Integer -> Int16 was really necessary, the others were just to confuse^d^d^d^d^d^d^d^d^d^dclarify the code. (The function Swap16 swaps the bytes of a 16 bit value, so $1234 becomes $3412.) The code works fine if range checking is turned off {$R-}. But with range checking turned on {$R+}, it fails for e.g. _Digits = 0, because a range check error occurs in the line marked above. Edit: The line the crash occurred was not the one multiplying with 11 but the one below. I would like to be able to keep range checking enabled in debug mode, so how can I modify the code to return the same results as if range checking was disabled? My idea was to change TempInt to an Int32 but I am unsure how to proceed. (I'm getting old. I'm sure this wouldn't have posed a problem for me 10 years ago. Or maybe it's the heat and not enough sleep.)
  14. You passed the test. 😉
  15. Isn't there something like {$SomeOption default} to reset an option to the value given in the project options? I seem to remember reading about that at some time in the what's new with Delphi Xxxx.
  16. I know now. I'm thinking about adding Assertions but only in debug mode. But that would make the code even less readable ... 😞 I could also use a sub range type.
  17. ... unless you know exactly which values you are dealing with.
  18. It turns out that the range for _Digits is indeed 0 .. 4095 because that value comes from the following code: // 3. Project the value on 12 Bit (11 = 2 * $5800 / 4096) // (The value of the laser laser is -$5800 to +$5800.) Value := Round(DigitInt / 11); // 4. signed -> unsigned 12 Bit Inc(Value, 2048); if Value < 0 then Value := 0; if Value > 4095 then Value := 4095; Digits := Value; // <== This is where the digits value come from So the changed function from above should do the trick as I tested it for _Digits = 0 .. 4095
  19. The point is that I want to find range check errors and fix them. That's why I have enabled them in the debug build (in Delphi 2007 where it was off by default).
  20. I hoped for a better way. This does the trick: function BuildDigits(_Digits: UInt16; _Invalids: UInt8): UInt16; var TempInt: Smallint; // 16 bit signed integer begin TempInt := _Digits; Dec(TempInt, 2048); TempInt := TempInt * 11; Move(TempInt, Result, SizeOf(Result)); Result := (Result and $FFFC) or (_Invalids and $03); Result := Swap16(Result); It returns the same values for _Digits = 0 .. 5000 and _Invalids = 0 .. $FF. Does anybody see anything wrong with this changed code? Now I need to check what the actual range of _Digits is. I hope it is documented somewhere. I guess it's 0 .. 4095 because the value is read from an analogue digital converter. But I'm not sure whether any preprocessing has already happened. (As said above: My excuse is that it's hot and that I haven't slept long enough.)
  21. Why? -2048 is a perfectly fine value for an Int16.
  22. Hm, yes, that's odd: -32678 <= -22528 <= 32767 Why didn't I see that? That was the line the debugger stopped on and I didn't question it. I'll need to have a closer look. Edit: The line the crash occurred was not the one multiplying with 11 but the one below: TempInt := (TempInt and $FFFC) or (_Invalids and $03); And that's probably because $FFFC is not an Int16. (I just changed the original post to reflect that.)
  23. Yes, that's how I "solved" it for now, but it feels like a hack. Edit: No, I put the whole function body into these, still feels like a hack.
  24. Yeah, I kind of knew that, I guess. It came up in a different discussion on a similar topic. That's why I use (U)Int(Len) types everywhere which are declared as being the correct length and also checked by an assertion. Apart from that, with names like these, it's clear what they are. (UInt32 = Cardinal which AFAIK is always 32 bit unsigned). Until somebody comes up with the great idea to change Int64 to be 128 bit for "compatibility reasons".... I guess I'll no longer be around by then and hope that there will be a mob to lynch that person.
×