Dezimalzahl in Bruch umrechnen

Ben2003

Aktiver Benutzer
Beiträge
33
Hallo,

hat schon jemand geschafft mit MySQL-Befehlen eine Dezimalzahl in einen Bruch umzurechnen?

In einer View wird anhand von mehreren Kriterien eine eine Dezimalzahl berechnet.

Der Client braucht die Dezimal-Zahl in zwei Angaben: Zähler und Nenner

z.B.
0,6 = 6/10 = gekürzt: 3/5
0,3333333 = 3333333/9999999 = gekürzt 1/3
0,125 = 125/100 = gekürzt 1/8
....

Kennt jemand eine oder mehrere mathematische Formeln, um das Ergebnis herauszubekommen?

Mein bisheriger Ansatz ist folgender:

Code:
set @dec = 0.125;


set @chk = 0;

SELECT CAST(@dec AS decimal(10,0)) INTO @chk;

SELECT @chk, @dec,IF (@dec = @chk, @dec,
  CONCAT(
  SUBSTRING(@dec, 2+LENGTH(SUBSTRING_INDEX(@dec,'.',1))), " Zähler ",
  POW(10,LENGTH(SUBSTRING(@dec, 2+LENGTH(SUBSTRING_INDEX(@dec,'.',1)))))
  , " Nenner "
  )
) Ausgabe;
 
Werbung:
Google: "dezimalzahl in bruch umschreiben"

1. Treffer:

Man schaut sich einfach an, wie viele Nachkommastellen die Dezimalzahl hat. Anschließend nimmt man sich die Zehnerpotenz, die so viele Nullen hat wie die Dezimalzahl Nachkommastellen. Diese schreibt man in den Nenner und die Dezimalzahl ohne Komma in den Zähler. Beispiel: 3,7=37/10, 0,001=1/1000, 4,02=402/100.
 
Hallo,

Google: "dezimalzahl in bruch umschreiben"

1. Treffer:

Genau diese Info habe ich auch gehabt. Mit diesen Informationen ist der erste Entwurf entstanden. :)

Mir geht es bei der Frage eher darum, ob es MySQL-spezifische Verfahren existieren oder ob jemand bereits eine vergleichbare Lösung erschaffen hat, um das Rad nicht neu erfinden zu müssen.
 
mal mit der gcd-Funktion (greatest common divisor) in PG13, um gleich die Kürzung hinzubekommen:

Code:
test=*# create or replace function dez2fractal (
  in dez numeric
  , out nenner int
  , out zaehler int
) as $$
  declare n int;
  z int;
  begin
    n=10^(length(regexp_replace(dez::text,'^.\.','')))::int;
    z=(regexp_replace(dez::text,'\.',''))::int;  
    nenner=n / gcd(n, z);
    zaehler = z / gcd(n, z);
  end;
$$ language plpgsql;
CREATE FUNCTION
test=*# select * from dez2fractal(0.125) ;
 nenner | zaehler
--------+---------
      8 |       1
(1 row)

test=*# select * from dez2fractal(0.6) ;
 nenner | zaehler
--------+---------
      5 |       3
(1 row)
 
Hallo,

vielen Dank.

Zur Info: Die fehlende GCD-Funktion kann auf dieser Webseite als Script heruntergeladen werden.

Hier das Script:

Code:
CREATE FUNCTION `GCD`(a INTEGER, b INTEGER) RETURNS int DETERMINISTIC
BEGIN
    DECLARE dividend INT;
    DECLARE divisor INT;
    DECLARE remainder INT;
    SET dividend := GREATEST(a, b);
    SET remainder := LEAST(a, b);
    SET divisor := 1;
    
    WHILE remainder != 0 DO
        SET divisor = remainder;
        SET remainder = MOD(dividend, divisor);
        SET dividend = divisor;
    END WHILE;
    
    RETURN divisor;
END
 
Zur Vollständigkeitshalber:

Mit diesem MySQL-Code kann eine Dezimalzahl in einen Bruch umgewandelt werden:

Code:
set @dez = 0.25;

SET @n = POW(10, LENGTH(REGEXP_REPLACE(@dez, '^.\.','')));
SET @z = REGEXP_REPLACE(@dez, '^.\.','');

SELECT @n / GCD(@n,@z) AS Nenner, @z / GCD(@n, @z) AS Zaehler

Zur Info: Die REGEXP_REPLACE-Funktion gibt es erst in Version 8.
 
Werbung:
Die zuvor genannte SQL-Befehle kommen nicht mit Periodischen Zahlen wie z.B. 0,33333333 (steht für 1/3) zurecht.

Diese Funktion kommt zumindest mit einfachen periodischen Zahlen zurecht:

Code:
CREATE FUNCTION dez2Fractal(dez DOUBLE)
  RETURNS VARCHAR(255) CHARSET utf8mb4
  DETERMINISTIC
BEGIN
 
  DECLARE z varchar(255);
  DECLARE n bigint;
  DECLARE ln bigint;
  DECLARE myOut varchar(255);
 
  SET z = REGEXP_REPLACE(dez, '^.\.','');
  set n = POW(10, LENGTH(z));
 
  SET ln = FLOOR((LENGTH(z) - LENGTH(REPLACE(z, SUBSTRING(z,1,1), ''))) / LENGTH(SUBSTRING(z,1,1)));
 
  IF length(z) = ln AND ln > 3 then
    set n=n-1;
  END IF;

  set myOut = CONCAT(ROUND(z / GCD(n, z),0),'/', ROUND(n / GCD(n,z),0));

  RETURN myOut;
END
 
Zuletzt bearbeitet:
Zurück
Oben