Programación General > Pascal

 Funcion convertir STRING a REAL

<< < (2/2)

baldur:
Muchas gracias por responder.
He tenido que crear 3 funciones. Una que me convierta un CHAR a un INTEGER, otra que me calcule las pontencias, y por último la global de StringAreal.
Pero tengo un problema y no logro solucionarlo. Y es que me convierte todo bien excepto los múltiplos de 10, osea los que tienen un 0 en el lugar de las unidades.
Por ejemplo, 9.5 o 11.1 o 2.4 me los convierte bien, pero si pongo 10 me devuelve 1, si pongo 20.5 me devuelve 2.5, osea que no guarda el 0 de las unidades.... os pongo aquí todo lo que he hecho, a ver si me podeis hechar una mano... Un Saludo y Gracias!


--- Código: Text --- Function CharToInt (caracter: char) : integer;Begin    CharToInt:=Ord(caracter)-48;{Devuelve un integer correspondiente con el número guardado en char}End; FUNCTION potencia( numero, exponente : integer ) : real;VAR resultado:integer VALUE 0;    expNeg:boolean;begin    resultado := 1;    If exponente<0 then     begin        exponente:=-(exponente);        expNeg:=true;    end;    while exponente > 0 do    begin    resultado := resultado*numero;    exponente:=exponente-1;    end;    If Not expNeg Then potencia:=resultado    Else        potencia:=1/resultado;end; FUNCTION StringToReal(cadenaNum:tCadenaFuncion):real;VAR cadenaEntera:string(length(cadenaNum));     cadenaDecimal:string(length(cadenaNum));        parteEntera:real VALUE 0;    AuxEntero:real VALUE 0;    parteDecimal:real VALUE 0;    AuxDecimal:real VALUE 0;    puntoEncontrado:boolean VALUE FALSE;    i:integer VALUE 0;BEGIN    cadenaEntera:='';    cadenaDecimal:='';    For i:=1 To length(cadenaNum) Do    begin        If (cadenaNum[i]='.') then puntoEncontrado:=TRUE        Else        begin            If Not puntoEncontrado Then cadenaEntera:=cadenaEntera+cadenaNum[i]            Else                cadenaDecimal:=cadenaDecimal+cadenaNum[i];        end;                end;     For i:=length(cadenaEntera) downto 1 Do    begin        AuxEntero:=parteEntera;        parteEntera:=(CharToInt(cadenaEntera[i])*potencia(10,(i-1)))+AuxEntero;       end;    If puntoEncontrado Then    begin        For i:=1 To length(cadenaDecimal) Do        begin            AuxDecimal:=parteDecimal;            parteDecimal:=(CharToInt(cadenaDecimal[i])*potencia(10,(-i)))+AuxDecimal;           end;        StringToReal:=parteEntera+parteDecimal;    end    Else        StringToReal:=parteEntera;END;  

SergioyoPlayer:
Mira; te puedes guiar por la "distancia" hasta la "coma" o fin de subcadena:

Pongamos 20.5:
la parte de la derecha dices que no tienes problema; la omito (yo la haría simétricamente al bucle de abajo)

Empleo la subcadena subcadena:=COPY(cadena,1,POS('.',cadena));

(si no tienes la función COPY, pues la haces a mano con un WHILE)

por ahora tenemos 0.5;

Luego, haces:

FOR i:=LENGTH(subcadena) DOWNTO 1 DO
 BEGIN
  numero:=numero+ChartoINT(subcadena)*Potencia(10,LENGTH(cadena)-i);
 END;

Que quedaría (por pasadas de bucle):
0.5+0*10^(2-2)=0.5+0*1=0.5
0.5+2*10^(2-1)=0.5*2*10^1=0.5+20=20.5

Espero no haberme equivocado :s

baldur:
Tío, muchiiiisimas GRACIAS!, me has salvado... :D

Pues yo tenía en que el exponente era i-1 y cambiadolo por lo que tu dices, length(cadenaEntera)-i ya rula...xD

Al final me han quedado así los dos bulces:


--- Código: Text ---         For i:=length(cadenaEntera) downto 1 Do    begin        AuxEntero:=parteEntera;        parteEntera:=(CharToInt(cadenaEntera[i])*potencia(10,length(cadenaEntera)-i))+AuxEntero;        end;  

--- Código: Text ---         For i:=1 To length(cadenaDecimal) Do        begin            AuxDecimal:=parteDecimal;            parteDecimal:=(CharToInt(cadenaDecimal[i])*potencia(10,(-i)))+AuxDecimal;           end;  
En la potencia de los decimales, mando como exponente la posición de la i pero negativa(para que de 0.1,0.2...etc), no sé si está correcto....es decir, por ahora me funciona, pero no sé si en algún caso puede cascar...

Gracias por todo y un Saludo!

SergioyoPlayer:
La primera asignación se puede omitir, poniendo en la segunda esto (dentro del FOR, me refiero):
   parteDecimal:=(CharToInt(cadenaDecimal)*potencia(10,(-i)))+ParteDecimal;

Esto es porque primero resuelve la función algebraica de la derecha, y el resultado lo mueve a la parte izquierda de la asignación. Sabiendo esto, te ahorras un paso omisible (inútil) como es el crear una variable auxiliar, y estar haciendo una asignacón por pasada de bucle.

Ánimo  :good:

Navegación

[0] Índice de Mensajes

[*] Página Anterior

Ir a la versión completa