Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Go Back   Foros Club Delphi > Principal > OOP
Register FAQ Members List Calendar Guía de estilo Search Today's Posts Mark Forums Read

Coloboración Paypal con ClubDelphi

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 26/05/2006
MasterXP MasterXP is offline
Miembro
 
Join Date: Jan 2005
Posts: 193
Poder: 22
MasterXP Va por buen camino
Fracciones en Delphi ¿No se puede?

Hola a todos, lo que quiero es convertir un decimal en una fraccion.

ejemplo: el decimal 0.14 convertirlo a la fraccion 1/7.

alguien me ayuda?
Reply With Quote
  #2  
Old 26/05/2006
delphi.com.ar's Avatar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Join Date: May 2003
Location: Buenos Aires, Argentina *
Posts: 5,964
Poder: 29
delphi.com.ar Va camino a la fama
Podrías utilizar los mismos mecanismos que se utilizan "en papel" para convertir un valor una expresión fraccionaria.


Quote:
Originally Posted by http://immortals.fake.hu/delphiportal/modules.php?name=News&file=print&sid=880
How to convert decimal numbers to fractions


Problem/Question/Abstract:

I'm looking for a function that I can pass in a decimal and return a fraction.

Answer:

Solve 1:

The ""Denominators"" parameter is an array of potential denominators that would be acceptable. For example, to get a fractional inch dimension with a power of 2 denominator, you'd pass [2, 4, 8, 16, 32] for that parameter, and the function will figure out which potential denominator will work best.

Código Delphi [-]
function ConvertFloatToFraction(const Value: Double;
  const Denominators: array of Integer): string;
var
  Index: Integer;
  TempDelta: Double;
  MinDelta: Double;
  TempNumerator: Integer;
  FracValue: Double;
  Numerator: Integer;
  Denominator: Integer;
  IntValue: Integer;
begin
  IntValue := Trunc(Value);
  FracValue := Abs(Frac(Value));
  MinDelta := 0;
  Numerator := 0;
  Denominator := 0;
  for Index := 0 to High(Denominators) do
  begin
    TempNumerator := Round(FracValue * Denominators[Index]);
    TempDelta := Abs(FracValue - (TempNumerator / Denominators[Index]));
    if ((Index = 0) or (TempDelta < MinDelta)) then
    begin
      MinDelta := TempDelta;
      Numerator := TempNumerator;
      Denominator := Denominators[Index];
    end;
  end;
  if (Numerator = Denominator) then
  begin
    IntValue := IntValue + Sign(IntValue);
    Numerator := 0;
  end;
  Result := '';
  if ((IntValue <> 0) or (Numerator = 0)) then
    Result := IntToStr(IntValue);
  if ((IntValue <> 0) and (Numerator <> 0)) then
    Result := Result + ' ';
  if (Numerator <> 0) then
    Result := Result + IntToStr(Numerator) + '/' + IntToStr(Denominator);
end;

Solve 2:

This function takes the number to convert, the fraction scale you want returned such as 8 for eighths or 10 for tenths, etc. and a boolean to tell it to round up or down the nearest fraction. It returns a string with the integer portion, a space and then the fraction portion. It will also reduce the fraction to the smallest common denominator. You can use the ErrorFactor variable to adjust the percentage of when to consider a number close enough to the next level to be close enough. I use 4 percent of the fractional scale value.
Código Delphi [-]
function ToFraction(num: double; scale: integer; RoundUp: boolean): string;

{Function to find greatest common denominator}
  function GCD(A, B: integer): integer;
  begin
    if (B mod A) = 0 then
      result := A
    else if (B mod A) = 1 then
      result := 1
    else
      result := GCD((B mod A), A);
  end;

var
  x, y: integer;
  ScaleFrac,
    NumFrac,
    ErrorFactor: double;
begin
  ScaleFrac := 1 / scale;
  NumFrac := Frac(Num);
  ErrorFactor := ScaleFrac * 0.04; {error factor of 4 percent}
  x := 0;
  while (((x + 1) * ScaleFrac) < (NumFrac + ErrorFactor)) do
    inc(x);
  if RoundUp then
    if (((((x + 1) * ScaleFrac) - NumFrac) / 2) > (ScaleFrac / 2)) then
      inc(x);
  if (x = 0) then {no fraction, just the integer portion}
  begin
    result := IntToStr(Trunc(Num))
  end
  else
  begin {reduce the fraction as much as possible}
    y := GCD(x, scale);
    while (y <> 1) do
    begin
      x := x div y;
      scale := scale div y;
      y := GCD(x, scale);
    end;
    result := IntToStr(Trunc(Num)) + ' ' + IntToStr(x) + '/' + IntToStr(scale);
  end;
end;
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Reply With Quote
  #3  
Old 26/05/2006
delphi.com.ar's Avatar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Join Date: May 2003
Location: Buenos Aires, Argentina *
Posts: 5,964
Poder: 29
delphi.com.ar Va camino a la fama
Las he probado despues de responder, y el resultado no fue bueno....
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Reply With Quote
  #4  
Old 26/05/2006
lpmlpm's Avatar
lpmlpm lpmlpm is offline
Miembro
 
Join Date: Aug 2005
Posts: 136
Poder: 22
lpmlpm Va por buen camino
0.14 = 14/100

Puedes partir de ahi y despues tratar de encontrar la minima expresión de ese número fraccionario...

ten en cuenta que 0.14 asi sin mas decimales no da exactamente 1/7 por lo que la minima expresión de 14/100 no es precisamente 1/7 sino algo así como 7/50

El algoritmo es simple se trata de encontrar el maximo comun divisor de ambos operadores y obtener la división de ambos...aqui mas o menos como lo simplificarias a partir de 2 cajas de edición con el numerador y el denominador:

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var a, b, mcd, mcm, tmp, resto: INTEGER;
begin
  a := StrToInt(Edit1.Text);
  b := StrToInt(Edit2.Text);
  tmp := a;
  mcd := b;
  repeat
    resto := tmp mod mcd;
    if resto <> 0
      then begin
      tmp := mcd;
      mcd := resto;
    end;
  until resto = 0;
  mcm := a * b div mcd;
  Edit1.Text := IntToStr(A div mcd);
  Edit2.Text := IntToStr(b div mcd);
end;

Saludos
__________________
"Lo mejor de no saber hacer nada es que se tiene mucho tiempo libre."
Reply With Quote
  #5  
Old 26/05/2006
luisgutierrezb luisgutierrezb is offline
Miembro
 
Join Date: Oct 2005
Location: México
Posts: 925
Poder: 21
luisgutierrezb Va por buen camino
hay 3 casos para la conversion de numeros decimales a fracciones

para ver como se resuelven los 3 casos entra aqui

asi que debes evaluar en cual caso cae el decimal y usar la solucion al respecto

Last edited by luisgutierrezb : 26/05/2006 at 23:48.
Reply With Quote
  #6  
Old 27/05/2006
MasterXP MasterXP is offline
Miembro
 
Join Date: Jan 2005
Posts: 193
Poder: 22
MasterXP Va por buen camino
Gracias a todos por responder.

"delphi.com.ar Las he probado despues de responder, y el resultado no fue bueno....", pienso lo mismo

lpmlpm, tu respuestas, no la entendi, no veo que es lo que hace, me aclaras un poquito

luisgutierrezb, estoy estudiando la pagina que me diste haber si hago mi propio algoritmo, pero si alguien me ayuda pos mejor, alguna ayudita mas?

salu2.
Reply With Quote
  #7  
Old 27/05/2006
lpmlpm's Avatar
lpmlpm lpmlpm is offline
Miembro
 
Join Date: Aug 2005
Posts: 136
Poder: 22
lpmlpm Va por buen camino
Ok. a ver ahora un poco más digerido:

Código Delphi [-]

uses Math;

function RealaFraccion(R: string): string;
var a, b, mcd, mcm, tmp, resto, NDecimales: INTEGER;
begin
  if StrToFloatDef(R, 0) = 0 then
  begin
    Result := '0';
    Exit;
  end;
  NDecimales := Length(R) - Pos('.', R);
  a := Trunc(StrToFloat(R) * Power(10, NDecimales));
  b := Trunc(Power(10, NDecimales));
  tmp := a;
  mcd := b;
  repeat
    resto := tmp mod mcd;
    if resto <> 0
      then begin
      tmp := mcd;
      mcd := resto;
    end;
  until resto = 0;
  Result := IntToStr(A div mcd) + '/' + IntToStr(B div mcd);
end;

//Y lo llamarías así:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption := RealaFraccion(Edit1.Text)
end;

Seguro que pudiera optimizarse en varias partes... es una versión preliminar y he sido un poco cobarde al no querer involucrarme demasiado con los diferentes tipos de datos flotantes que hay pero en mi experiencia trabajar de este modo te da mucha tranquilidad y es mejor llevarla tranquila por ese lado... prefiero tratar los flotantes limitados como estos como cadenas para evitar conflictos y respetar al máximo el número real que tu quieres convertir en fracción...

Saludos
__________________
"Lo mejor de no saber hacer nada es que se tiene mucho tiempo libre."
Reply With Quote
  #8  
Old 28/05/2006
MasterXP MasterXP is offline
Miembro
 
Join Date: Jan 2005
Posts: 193
Poder: 22
MasterXP Va por buen camino
Gracias pmlpm, ahora si se entendió, dejame probarlo y te cuento
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Se puede crear Dns por codigo Delphi ronimaxh Conexión con bases de datos 0 09/08/2005 16:38
¿Se puede personalizar el Outlook con Delphi? andressanchez Varios 6 26/07/2005 17:33
¿Cuan costoso puede ser Delphi? MARVIALI Conexión con bases de datos 1 07/12/2004 18:37
Como se puede hacer un MDI en Delphi k2k2k2 Varios 5 23/05/2004 12:19
Delphi puede parametrizarse? squenda OOP 2 03/03/2004 14:17


All times are GMT +2. The time now is 10:08.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi