Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 03-04-2014
novato_erick novato_erick is offline
Miembro
 
Registrado: ago 2010
Ubicación: Panamá
Posts: 396
Poder: 14
novato_erick Va por buen camino
Cita:
Casimiro:
Claro, pero eso es así en todos los sistemas, no puedes usar un float para eso
Es cierto a duro golpe me acabo de percatar de eso..

Cita:
Si, y también agregar que podes utilizar la función ROUND de Firebird.

Como ejemplo:
Código SQL [-]
SELECT ROUND(3.141592654, 6) FROM RDB$DATABASE; -- 3,141593000
acabo de intentarlo con tu sugerencia ecfisa, pero el resultado es el mismo ejemplo:
Código SQL [-]
SELECT ROUND(11.9954967498779, 6) FROM RDB$DATABASE; -- 11.995496

el asunto como lo mencioné antes la db tiene el campo de tipo Float el cual todo numero que ingrese me manda hasta doce decimales.

la solución creo que estaría en cambiar el tipo de dato a Decimal 12, 2 como lo puse en el post anterior sin embargo me acabo de encontrar que no es compatible Decimal con float En firebird aunque tambien se que no es exclusivo de firebird la incopatibilidad de datos ya ingresado para codificar el campo;

nuevamente Gracias Chicos... Es bueno saber que no estoy solo en esto....

Saludos
Responder Con Cita
  #2  
Antiguo 03-04-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Cita:
Empezado por novato_erick Ver Mensaje
...
acabo de intentarlo con tu sugerencia ecfisa, pero el resultado es el mismo...
Si si, por supuesto. Funciona del mismo modo que SimpleRoundTo, solo lo mencioné como alternativa para, por ejemplo, traer el resultado ya redondeado desde la consulta.

Como te comentó Casimiro es el comportamiento natural de todos los sistemas (al menos los que conozco).

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 03-04-2014
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
novato_erick,

Cita:
Empezado por novato_erick
...Alguna mejor idea de funciones de redondeo que me retorne valores deseados reales...
Revisa este código:
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, Math;

type
  TForm1 = class(TForm)      
    RadioGroup1: TRadioGroup;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
   RadioGroup1.ItemIndex := 0;
end;

// Realiza diversos tipos de redondeo
procedure TForm1.Button1Click(Sender: TObject);
var
   N1 : Double;
   E : Integer;

begin

   {

   -function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode
  
   Sets the FPU rounding mode.
  
   (RoundMode)
   rmNearest : Rounds to the closest value.
   rmDown : Rounds toward negative infinity.
   rmUp : Rounds toward positive infinity.
   rmTruncate : Truncates the value, rounding positive numbers down and negative numbers up.
  
   -function RoundTo(const AValue: Double; const ADigit: TRoundToRange): Double;
  
   Rounds a floating-point value to a specified digit or power of ten using “Banker’s rounding”.

   }

   N1 := 2.718281;

   case RadioGroup1.ItemIndex of

      0 : begin
             SetRoundMode(rmUp);
             // Muestra 2.72
             ShowMessage(FormatFloat('#,###,###.00',RoundTo(N1,-2)));
          end;

      1 : begin
             SetRoundMode(rmDown);
             // Muestra 2.71
             ShowMessage(FormatFloat('#,###,###.00',RoundTo(N1,-2)));
          end;

      2 : begin
             SetRoundMode(rmNearest);
             // Muestra 2.72
             ShowMessage(FormatFloat('#,###,###.00',RoundTo(N1,-2)));
          end;

      3 : begin
             SetRoundMode(rmTruncate);
             // Muestra 2.71
             ShowMessage(FormatFloat('#,###,###.00',RoundTo(N1,-2)));
          end;

   end;

end;

// Estable el número de decimales (Truncado) sin redondeo de valores doubles
function DoubleDecimals(Number : Double; Decimal : Integer) : Double;
var
   AuxNumber : String;

begin

   AuxNumber := FloatToStr(Number);

   if Pos('.',AuxNumber) > 0 then
      Result := StrToFloat(Copy(AuxNumber,1,Pos('.',AuxNumber) + Decimal))
   else
   if Pos(',',AuxNumber) > 0 then
      Result := StrToFloat(Copy(AuxNumber,1,Pos(',',AuxNumber) + Decimal))
   else
      Result := Number;

end;

// Convierte un valor de n decimales a m decimales sin redondeo
procedure TForm1.Button2Click(Sender: TObject);
var
   N1 : Double;
   E : Integer;

begin

   N1 := 2.718281;

   // Convierte 2.718281 en 2.71, se establece el truncado de decimales sin redondeo a 2
   N1 := DoubleDecimals(N1,2);

   // Muestra 2.71
   ShowMessage(FloatToStr(N1));

end;

end.
El código anterior permite hacer diferentes tipos de ajustes decimales con redondeo y sin redondeo.

Espero sea útil

Nelson.

Última edición por nlsgarcia fecha: 03-04-2014 a las 22:06:06.
Responder Con Cita
  #4  
Antiguo 03-04-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.101
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Si quieres redondear, por ejemplo, a 2 decimales:
Código Delphi [-]
resultado := redondeo(importe,2);
Código Delphi [-]
uses Math;

...
...

function Redondeo (valor: Double; decimales: integer = 0): Double;
var
  factor: Double;
begin
  factor := IntPower(10,decimales);
  //
  if valor > 0 then
    Result := (trunc((valor*factor)+0.5)) / factor
  else
    Result := (trunc((valor*factor)-0.5)) / factor;
end;
Responder Con Cita
  #5  
Antiguo 04-04-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola novato_erik.

Tanto Delphi como Firebird, redondean (y lo hacen muy bién) con SimpleRoundTo() y ROUND(), pero si sos de los que te gusta ir a las bases, te pongo otra opcion.

Delphi:
Código Delphi [-]
function Redondear(const Numero: Double; const Digitos: Integer): Double;
var
  Factor: Double;
begin
  Factor:= Abs(Exp(Ln(10)*(-Digitos)));
  Result:= Trunc((Numero/Factor) + 0.5) * Factor;
end;

Firebird:
Código SQL [-]
SET TERM ^ ;

CREATE OR ALTER PROCEDURE SP_ROUND(NUMERO DOUBLE PRECISION, DIGITOS INTEGER)
RETURNS(RESULT DOUBLE PRECISION)
AS
  DECLARE VARIABLE FACTOR DOUBLE PRECISION;
BEGIN
  FACTOR = ABS(EXP(LN(10)*(-DIGITOS)));
  RESULT = TRUNC((NUMERO/FACTOR)+0.5)*FACTOR;
  SUSPEND;
END^

SET TERM ; ^

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #6  
Antiguo 21-04-2014
novato_erick novato_erick is offline
Miembro
 
Registrado: ago 2010
Ubicación: Panamá
Posts: 396
Poder: 14
novato_erick Va por buen camino
Hola chicos definitivamente cambié en la base de datos en firebird el tipo de campo a decimal 12,2 corrigió muchos de mis problemas pero como dije muchos de mis problemas quedando algunos al azar en la aplicación con el asunto de los redondeos.

nuestro amigo ecfisa me dice:

Cita:
Tanto Delphi como Firebird, redondean (y lo hacen muy bién) con SimpleRoundTo() y ROUND()
lo hice y como respaldo busqué la ayuda de Delphi y salió esto:

Cita:
function SimpleRoundTo(const AValue: Single; const ADigit: TRoundToRange = -2): Single;
function SimpleRoundTo(const AValue: Double; const ADigit: TRoundToRange = -2): Double;
function SimpleRoundTo(const AValue: Extended; const ADigit: TRoundToRange = -2): Extended;

SimpleRoundTo(1234567, 3)
1234000

SimpleRoundTo(1.234, -2)
1.23

SimpleRoundTo(1.235, -2) //este redondeo es que me interesa
1.24

SimpleRoundTo(-1.235, -2)
-1.23
en fin a la hora de utilizar la función me sale 5.26 en vez de5.27

Código Delphi [-]
 5.26 := simpleroundto(5.265, -2)

en fin necesito esto porque en mi país están utilizando las dichosas impresoras fiscales el cual ese valor de 5.265 ella misma me hace el calculo y lo guarda como 5.27 mientras que en la aplicación simpre me está mostrando el 5.26 aun utilizando la función Simpleroundto.

Saludos
Responder Con Cita
  #7  
Antiguo 21-04-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.101
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Pues usa la función que he puesto yo antes.
Y veo que ecfisa también.
Creo que con ellas no tendrás ese problema.
Responder Con Cita
  #8  
Antiguo 22-04-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Cita:
Empezado por novato_erick Ver Mensaje
...
en fin a la hora de utilizar la función me sale 5.26 en vez de5.27

Código Delphi [-]
 5.26 := simpleroundto(5.265, -2)

en fin necesito esto porque en mi país están utilizando las dichosas impresoras fiscales el cual ese valor de 5.265 ella misma me hace el calculo y lo guarda como 5.27 mientras que en la aplicación simpre me está mostrando el 5.26 aun utilizando la función Simpleroundto.
Hola novato_erick.

A ver... proba de este modo:
Código Delphi [-]
function Redondear(const Numero: Double; const Cifras: Integer): Extended;
var
  pd: Extended;
begin
  pd := Exp(Ln(10)*Cifras);
  if Trunc(Frac(Numero)*pd) mod 10 < 5 then
    Result:= Round(Numero*pd)/pd
  else
    Result:= Round(Numero*pd+1/pd)/pd;
end;

Ejemplo:
Código Delphi [-]
   FloatToStr(Redondear(5.265, 2)); // 5.27


Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #9  
Antiguo 22-04-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.101
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Si quieres redondear, por ejemplo, a 2 decimales:
Código Delphi [-]
]resultado := redondeo(importe,2);

Código Delphi [-]
function Redondeo (valor: Double; decimales: integer = 0): Double;
var
  factor: Double;
begin
  factor := IntPower(10,decimales);
  //
  if valor > 0 then
    Result := (trunc((valor*factor)+0.5)) / factor
  else
    Result := (trunc((valor*factor)-0.5)) / factor;
end;
Como dos gotas de agua, "me han copiado"
Responder Con Cita
  #10  
Antiguo 22-04-2014
novato_erick novato_erick is offline
Miembro
 
Registrado: ago 2010
Ubicación: Panamá
Posts: 396
Poder: 14
novato_erick Va por buen camino
hola Al González cómo siempre tus aportes igual que el de tus colegas casimiro, ecfisa son un ejemplo de conocimiento y enriquecimiento en este foro los felicito y les doy las gracias..

Al González
Cita:
n realidad, las funciones de redondeo nativas de Delphi no fueron de todo buenas en las versiones de años anteriores. En Delphi 7, por ejemplo, es evidente un bug de signo en la función SimpleRoundTo.
Tengo XE disculpen por no aclarar eso desde el seguimiento con este hilo.

Algo curioso casimiro

utilicé tu función que me recomendabas y la de ecfisa también pero tengo el mismo problema no me redondean cuando el tercer valor decimal ejemplo: 5.265 u otro valores. por eso busqué la ayuda de delphi y otros hilos es extraño que no suceda muy a menudo.

ya me está volviendo loco ese redonde porque la imp fiscal si lo hace siempre para arriba y en cosasiones es 0.01 centécimos el valor que me hace falta en la factura...


Saludos chicos

pd: disculpen si no he mencionado a las otras personas que me han siempre colaborado pero son varios que olvido sus nick... pero igual manera son muy útiles sus aportes gracias chicos

Última edición por novato_erick fecha: 22-04-2014 a las 19:40:39.
Responder Con Cita
  #11  
Antiguo 22-04-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.101
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Pon un ejemplo concreto, con código, datos, valores, todo.
¡Y a saber cómo redondea esa impresora!
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


La franja horaria es GMT +2. Ahora son las 03:17:02.


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