Delphi XE7 - Field FTBcd - Number is out of Range - delphi

I am migrating an application from Delphi 2010 to Delphi XE7 that it uses some old Paradox Table with BDE. I have some fields formed BCD (#) Size 4 that in Delphi 2010 were managed as.asfloat
example
TABELLA1.Fieldbyname('FIELDBCD').AsFloat: = TABELLA2.Fieldbyname('Number').AsFloat;
without any problem.
In the converted program any type of assignment goes to error signalling EDBEngineError Number is out of range.... this even if I simply digit the value from a DBGrid.
Do you know of BUG in the management of the fields BCD in Delphi XE7 or must they have managed in different way?
Thanks
Mirko

The ask is old, but I was still facing this problemn these days. I suggest confirm three properties.
precision - (It need to be the significative part and the fractionary part). For example, in data base the field is numeric(8,4), so here the correct value is 12
size - (Just the faccionary part of the number). In our example, the correct value is 4
DisplayWidth - Here we uses the value of the precision + 1, for the comma.

Related

Delphi + Firebird (using DBExpress): aggregate issue with TFMTBCDField

I have a table with a NUMERIC(15,2) field in my database. In Delphi, I use the trio TSQLDataset + TDataSetProvider + TClientDataSet. This field is created as TFMTBCDField. The problem is that I need to use an Aggregate field in my ClientDataSet in order to sum the values and for some reason it's not calculated correctly (see image below). However, if I set my field type as DOUBLE PRECISION in my database (Delphi creates the field as TFloatField in dataset) the aggregate works as expected.
PS: I've read somewhere that is better using NUMERIC than DOUBLE PRECISION in Firebird.
I'm using Delphi XE7 and Firebird 2.5
How do you deal with this issue?
Thanks.

Why has the Cardinal type in my application changed?

I have a program here which was working fine in Delphi 3 that I compiled and tested on Turbo Delphi 2006 and found a problem. The problem is this: I was using "cardinal" data types as an index for something. It worked in Delphi 3, but I found values were greater than they should be in the Turbo Delphi 2006 compiled version by about 128-256 or so depending on the specific data. Changing these data types to "longint" fixed the problem so the program worked correctly with both compilers.
The question: Why is this?
My understanding was that Cardinal data types were just typical unsigned integer data. This is consistent with the application of them in this program, especially proved by the fact that the Delphi 3 compilation worked correctly. So why did the Turbo Delphi 2006 compilation not work?
In Delphi, unsigned types are just subrange types of the next larger signed type. In Delphi 3, there is no 64-bit type, so there is no next larger type for Cardinal to be a subrange of. Cardinal is a signed type in Delphi 3 because of a technical limitation in the language. Delphi 4 introduced Int64, and Cardinal was made to be an unsigned subrange of that type (and then the limitation was that the was no unsigned 64-bit type).
In short, you were never getting true unsigned behavior in the first place. Now that you've upgraded, you've exposed long-present problems that have always been in your code.
That your code compiled is no proof that your code was correct. Delphi 3 cannot enforce rules that require types it doesn't really have.

Internal format of TDateTime in Delphi 7?

I've spent many hours researching this and am pretty stuck: my question is - has the internal format of a Delphi TDateTime changed between Delphi 7 (released in 2002 or so) and today?
Scenario: I'm reading a binary logfile created by a Delphi 7 app, and the vendor tells me it's a TDateTime in the record, but decoding the bits shows it's clearly not standard IEEE 754 floating point even though the TDateTime produced by modern Delphi is.
But it's some kind of floating point with around 15 bits of exponent and 45 bits of significand (as opposed to 11 and 53 bits in IEE754), and the leading bit is a 1 (which in IEE754 indicates a negative number) for numbers that are clearly not negative, such as the current date/time.
Hints in old documentation suggested that TDateTime "read as" a double but wasn't necessarily represented internally as one, which means that the internal format would be mostly invisible except where these TDateTimes were written out in binary form.
My suspicion is that the change occurred with Delphi 8, which added .NET support, but I simply can't find any references to this anywhere. I have perl code (!) that picks apart these types mostly working, but I'd love to find a formal spec so I can do it properly.
Any old-timers run into this?
~~~ Steve
Nothing has changed since Delphi 7. In Delphi 7, and in fact previous versions, TDateTime is IEEE754, measuring the number of days since the Delphi epoch.
You are going to need to get in touch with the software vendor and try to work out what this data's format really is. It would be surprising if the format was a non-IEEE754 floating point data type. Are you quite sure that it is floating point?
As for BCB3, BCB6 and D4, it's exactly the IEEE 754 Double-precision floating-point format, in the VCL source file system.pas (as included in BCB6) it's defined by thus:
TDateTime = type Double;

Using decimal data type to work with monetary values with db2 and delphi 2010

I'm using delphi 2010 with db2 9.7 Express-C and I have a database that has several fields of decimal type to work with monetary values. Now I see that there are some problems using it, like the 9.20 value displays the value 9.19999980926514 in my front-end. I need to change all the fields in my database to DECFLOAT or is there a function, property in tfield or other alternative to solve it ?
Thanks.
Davis
working directly with monetary decimals is almost always a problem. due to different conversions made from the database to your front-end application, it is possible to lose or to gain(this applies to most of the financial systems also - see bankers rounding).
I suggest you to use the RoundTo function before making operations/display/etc. A very good article about rounding http://docwiki.embarcadero.com/RADStudio/XE2/en/Floating-Point_Rounding_Issues
Another suggestion will be using of the Currency type. Here is a question on SO with good explanation about this type How to avoid rounding problems when comparing currency values in Delphi?

Delphi Programming to convert 66-bit value (Hex) to Decimal [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Large numbers in Pascal (Delphi)
I am trying to convert a 66bit value to decimal.
I note that the largest data type in delphi in int64 which can only allow 64bit data.
example of delphi code for such conversion is
result := strtoInt64('FFFFABCDEFF123456');
Please advice how to use delphi to this without returning out of range error.
Muda
Decimal in Delphi is called currency it uses 8 bytes = 64 bits.
You'll have to create your own type, see this article: http://www.delphi3000.com/articles/article_3772.asp
It describes how to create a 128bit integer.
Here's a bignum lib for Delphi: http://cc.embarcadero.com/item/27789
See also this question: Large numbers in Pascal (Delphi)
If you can afford having some rounding errors, you can use the Extended type. That's an easy solution. I remember reading somewhere that it won't be supported in 64bit Delphi anymore though, so I personally wouldn't use it if it can be avoided.
Anyway, do you really want to do calculations on your number? Are you sure you don't just want to have an array (of bytes for example)? If that is the case, you should look at HexToBin().
Documentation: http://docwiki.embarcadero.com/VCL/en/Classes.HexToBin
Example where you can see it in use: http://docwiki.embarcadero.com/CodeExamples/en/HexEncoding_(Delphi)

Resources