Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2009-12

floating point mask

8 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

ik

Hello,

I'm trying to create some sort of calculator for specific task. I require to allow to input only floating point or integer numbers. I thought to use TMaskEdit for it, but how can i tell it a rule to allow me arbitrary number length including a floating point on arbitrary position ?

In regex such rule will look like:

^(\d+|\d+\.\d+)$

Does the TMaskEdit capable of defining such pattern (not in the syntax of regex) ? If not, is there any tool that can provide me this type of patterns ?

Thanks,
Ido

http://ik.homelinux.org/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20091207/efda60ae/attachment.html>

Reply by email

Hans-Peter Diettrich
to ik
Show quoted text 5 lines
I'm trying to create some sort of calculator for specific task. I require to allow to input only floating point or integer numbers. I thought to use TMaskEdit for it, but how can i tell it a rule to allow me arbitrary number length including a floating point on arbitrary position ?

TMaskEdit IMO has very limited use, restricted to the insertion or removal of fixed "decoration" for some input.

Show quoted text 7 lines
In regex such rule will look like: ^(\d+|\d+\.\d+)$ Does the TMaskEdit capable of defining such pattern (not in the syntax of regex) ? If not, is there any tool that can provide me this type of patterns ?

You can use any input component, and check e.g. in OnKeyPress whether the resulting string would be valid. If not, reject the input character.

You can use any regex library for the check, but IMO that's overkill with a single constant format. In your case I'd use the conversion function itself, e.g. Val(), to determine whether the input is valid.

DoDi

Reply by email

David Emerson
to Hans-Peter Diettrich
Show quoted text 7 lines
You can use any input component, and check e.g. in OnKeyPress whether the resulting string would be valid. If not, reject the input character. You can use any regex library for the check, but IMO that's overkill with a single constant format. In your case I'd use the conversion function itself, e.g. Val(), to determine whether the input is valid.

This has the disadvantage of sometimes making it difficult to type things naturally. e.g. if I started by typing "-" that could be rejected, since I haven't yet input a number to make negative.

For this reason I much prefer to have some kind of visible indication as to whether an input is presently valid: show the user whether their input is presently in a good state, but don't restrict the input in that way. One must do some validation later on, but that should probably be done anyway.

Of course, if you have a set of all the valid characters ['-', '.', '0'..'9', 'e', 'E', '+'], it's not unreasonable to restrict characters outside that set. But make sure the set is complete-- at first I overlooked "e+" which is valid for val (string, real)

~D.

Reply by email

Alexander Klenin
to David Emerson
David Emerson wrote 5 lines
Of course, if you have a set of all the valid characters ['-', '.', '0'..'9', 'e', 'E', '+'], it's not unreasonable to restrict characters outside that set. But make sure the set is complete-- at first I overlooked "e+" which is valid for val (string, real)

No, it is not:

t.pas
---
var

  x: Double;
  d: Integer;

begin

  Val('e+', x, d);
  Writeln(x, ' ', d);

end.
---
dcc32 -cc t.pas
t.exe
==>
0.00000000000000E+0000 3
---
fpc t.pas
t.exe
==>
0.00000000000000E+000 1

So both Delphi and FPC reject 'e+' as a floating-point value, although with different error positions.
The latter is probably a compatibility bug in FPC's Val procedure.

Alexander S. Klenin

Reply by email

waldo kitty
to Alexander Klenin

sorry but what is the code below supposed to be showing??

Alexander Klenin wrote 33 lines
On Tue, Dec 8, 2009 at 03:49, David Emerson wrote: > Of course, if you have a set of all the valid characters > ['-', '.', '0'..'9', 'e', 'E', '+'], it's not unreasonable to restrict > characters outside that set. But make sure the set is complete-- at > first I overlooked "e+" which is valid for val (string, real) > No, it is not: t.pas --- var x: Double; d: Integer; begin Val('e+', x, d); Writeln(x, ' ', d); end. --- dcc32 -cc t.pas t.exe ==> 0.00000000000000E+0000 3 --- fpc t.pas t.exe ==> 0.00000000000000E+000 1 So both Delphi and FPC reject 'e+' as a floating-point value, although with different error positions. The latter is probably a compatibility bug in FPC's Val procedure.

Reply by email

Alexander Klenin
to waldo kitty
waldo kitty wrote
sorry but what is the code below supposed to be showing?? > On Tue, Dec 8, 2009 at 03:49, David Emerson wrote: >> at first I overlooked "e+" which is valid for val (string, real)

To which i replied:

Alexander Klenin wrote: > No, it is not:

... and demonstrated that with the code example.

Alexander S. Klenin

Reply by email

David Emerson
to Alexander Klenin: No, it is not: t.pas --- var x: Double; d: Integer; begin Val('e+', x, d); Writeln(x, '…
David Emerson wrote: > at first I overlooked "e+" which is valid for val (string, real)
Alexander Klenin wrote
No, it is not: Val('e+', x, d);

What I meant is that I first overlooked 'e' and '+' as valid characters that can appear together within a string to be converted to a float. The following compiles and works as expected:

var x : real;
begin
  val ('4.1e+5', x);  // "e+" is valid for val (within context)
  writeln (x);
end.

The point I was making was that if someone is going to make a floating point mask (note the subject...) that one should be careful not to exclude any valid characters if restricting input by character. I'm not sure if the set I suggested ['-', '.', '0'..'9', 'e', 'E', '+'] is complete.

Cheers,
~David.

Reply by email

ik
to David Emerson

You are over engineering this.
Here is what I did (not completed yet):

  TfrmCalculator = class (TForm)
    edtAmount : TEdit ;
    edtPerc : TEdit ;
    edtResult : TEdit ;
    procedure edtAmountKeyDown (Sender : TObject ; var Key : Word ;
      Shift : TShiftState );
    procedure edtAmountKeyPress (Sender : TObject ; var Key : char );
    procedure FormCreate (Sender : TObject );
  private
    { private declarations }
  public
    { public declarations }
    FloatingPoint : array [1..2] of Boolean;
  end;
procedure TfrmCalculator.edtAmountKeyPress (Sender : TObject ; var Key :
char);
 function CanFloatingPoint : boolean;
 begin
   Result := (not FloatingPoint[TCustomEdit(Sender).Tag]) and
             (Length(TCustomEdit(Sender).Text) > 0);
 end;
var
  OldSelStart : integer;
begin
  if (Key = '.') and (CanFloatingPoint) then
    begin
      FloatingPoint[TCustomEdit(Sender).Tag] := True;
    end
  else
  if (Key = #8) then
    begin
      OldSelStart := TCustomEdit(Sender).SelStart;
      TCustomEdit(Sender).SelStart := OldSelStart - 1;
      TCustomEdit(Sender).SelLength := 1;
      if TCustomEdit(Sender).SelText = '.' then
        begin
          FloatingPoint[TCustomEdit(Sender).Tag] := False;
        end;
      TCustomEdit(Sender).SelLength := 0;
      TCustomEdit(Sender).SelStart := OldSelStart;
    end
  else if (Key in ['0'..'9']) then
    Key := Key
  else         //Floating point not allowed
    Key := #0;
end;
procedure TfrmCalculator.edtAmountKeyDown (Sender : TObject ; var Key : Word
;
  Shift : TShiftState);
var
 Selected : Integer;
 OldStart : Integer;
begin
  Selected := TCustomEdit(Sender).SelLength;
  OldStart := TCustomEdit(Sender).OldStart;
  if Key = VK_DELETE then
    begin
      if (Selected = 0) then
        begin
          TCustomEdit(Sender).SelLength := 1;
          if (TCustomEdit(Sender).SelText = '.') then
            FloatingPoint[TCustomEdit(Sender).Tag] := False;
          TCustomEdit(Sender).SelLength := 0;
          TCustomEdit(Sender).SelLength := OldStart;
        end
      else
      if (Selected = 1) then
        begin
          if (TCustomEdit(Sender).SelText = '.') then
            FloatingPoint[TCustomEdit(Sender).Tag] := False;
        end
      else if Selected > 1 then
             begin
              if Pos('.', TCustomEdit(Sender).SelText) > 0 then
                FloatingPoint[TCustomEdit(Sender).Tag] := False;
             end;
    end;
end;
procedure TfrmCalculator.FormCreate (Sender : TObject);
begin
  FillChar(FloatingPoint, SizeOf(FloatingPoint) , 0);
end;

I'm thinking in creating such a component btw, if anyone is interested.

Ido

http://ik.homelinux.org/

David Emerson wrote 33 lines
> David Emerson wrote: > > at first I overlooked "e+" which is valid for val (string, real) Alexander Klenin wrote: > No, it is not: > Val('e+', x, d); What I meant is that I first overlooked 'e' and '+' as valid characters that can appear together within a string to be converted to a float. The following compiles and works as expected: var x : real; begin val ('4.1e+5', x); // "e+" is valid for val (within context) writeln (x); end. The point I was making was that if someone is going to make a floating point mask (note the subject...) that one should be careful not to exclude any valid characters if restricting input by character. I'm not sure if the set I suggested ['-', '.', '0'..'9', 'e', 'E', '+'] is complete. Cheers, ~David. -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20091209/d28bca10/attachment.html>

Reply by email