Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 26-05-2006
MasterXP MasterXP is offline
Miembro
 
Registrado: ene 2005
Posts: 193
Poder: 20
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?
Responder Con Cita
  #2  
Antiguo 26-05-2006
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Podrías utilizar los mismos mecanismos que se utilizan "en papel" para convertir un valor una expresión fraccionaria.


Cita:
Empezado por 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.
Responder Con Cita
  #3  
Antiguo 26-05-2006
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
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.
Responder Con Cita
  #4  
Antiguo 26-05-2006
Avatar de lpmlpm
lpmlpm lpmlpm is offline
Miembro
 
Registrado: ago 2005
Posts: 136
Poder: 19
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."
Responder Con Cita
  #5  
Antiguo 26-05-2006
luisgutierrezb luisgutierrezb is offline
Miembro
 
Registrado: oct 2005
Ubicación: México
Posts: 925
Poder: 19
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

Última edición por luisgutierrezb fecha: 26-05-2006 a las 23:48:39.
Responder Con Cita
  #6  
Antiguo 27-05-2006
MasterXP MasterXP is offline
Miembro
 
Registrado: ene 2005
Posts: 193
Poder: 20
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.
Responder Con Cita
  #7  
Antiguo 27-05-2006
Avatar de lpmlpm
lpmlpm lpmlpm is offline
Miembro
 
Registrado: ago 2005
Posts: 136
Poder: 19
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."
Responder Con Cita
  #8  
Antiguo 28-05-2006
MasterXP MasterXP is offline
Miembro
 
Registrado: ene 2005
Posts: 193
Poder: 20
MasterXP Va por buen camino
Gracias pmlpm, ahora si se entendió, dejame probarlo y te cuento
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Se puede crear Dns por codigo Delphi ronimaxh Conexión con bases de datos 0 09-08-2005 16:38:11
¿Se puede personalizar el Outlook con Delphi? andressanchez Varios 6 26-07-2005 17:33:07
¿Cuan costoso puede ser Delphi? MARVIALI Conexión con bases de datos 1 07-12-2004 18:37:25
Como se puede hacer un MDI en Delphi k2k2k2 Varios 5 23-05-2004 12:19:18
Delphi puede parametrizarse? squenda OOP 2 03-03-2004 14:17:04


La franja horaria es GMT +2. Ahora son las 14:17:20.


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