Nie do końca rozumiem o co pytasz. Tj. pytasz jak zamienić long double na reprezentacje naukową algorytmicznie? Czy po prostu potrzebujesz decymalne floaty?
Jeśli to drugie, to niektóre kompilatory mają do tego jakieś tam wsparcie (np. GCC), ew. są całkiem solidne biblioteki do tego (jak np. ta).
Jeśli natomiast chcesz zobaczyć jak wygląda zwykły binarny float (niezależnie od wielkości) w notacji naukowej, to najprostszy sposób to po prostu wyliczenie logarytmu o podstawie 10 z liczby, i potem podzielenie liczby przez 10 do potęgi podłogi z tego tam logarytmu.
Pseudokod (zgodnie z zasadą, że dobrze napisany pseudokod to poprawny Python):
import math
def to_sci(f):
if f == 0.0: # log(0) won't work
return "0"
p = math.log(f, 10)
ip = math.floor(p)
num = f / 10**ip
return f"{num}e{ip}"
print(to_sci(1.23e11))
print(to_sci(1.23e-11))
print(to_sci(0))
Czyli de facto problem został sprowadzony do zwykłej konwersji float binarny → reprezentacja decymalna + kilka natywnych operacji na floatach.
Jeśli nie interesuje Cię za bardzo dokładny wynik, a chcesz koniecznie operować na binarnej mantysie/wykładniku/etc, to tak na szybko wykminiłem coś takiego:
import math
def to_sci(exp, mant):
# Assuming this is a binary float.
# Assuming mant is already decoded as a float, e.g. 1.23.
# Assuming exp is already decoded as an int, e.g. 123.
# Ignoring any edge cases / zero / etc because I'm lazy.
# Ignoring sign because I'm, yes, I'm lazy.
p = 2**exp
l10 = math.floor(math.log(p, 10))
p10 = 10**l10
num = mant * (p / p10)
if num >= 10.0:
num /= 10.0
l10 += 1
return f"{num}e{l10}"
def float_to_exp_mant_hack(f):
# This is a hack, just for demo purposes (because I'm too lazy to
# decode this on binary level).
# >>> 1.23e11.hex()
# '0x1.ca35f0e000000p+36'
mant, exp = f.hex()[2:].split("p")
exp = int(exp)
mant = float.fromhex(mant)
return exp, mant
print(to_sci(*float_to_exp_mant_hack(1.23e11))) # Output: 1.23e11
print(to_sci(*float_to_exp_mant_hack(1.23e-11))) # Output: 1.23e-11
Generalnie wyliczanie całego p / p10 oraz l10 można spokojnie stabelaryzować (tj. wyliczyć wcześniej i wrzucić w jakąś tabelkę), żeby nie bawić się z wielkimi potęgami cały czas. Wtedy całość sprowadzi się do prostego mnożenia i ew. dzielenia/dodawania. No i typowej konwersji floata na wartość decymalną.