staging.inyokaproject.org

Das Numerische Ergebniss ist außerhalb des gültigem Bereiches

Status: Ungelöst | Ubuntu-Version: Ubuntu 16.04 (Xenial Xerus)
Antworten |

oeztuerk_42

Anmeldungsdatum:
19. Mai 2019

Beiträge: 25

Ich hab ein Programm geschrieben, welche die eingegebene Zahl in Wörtern umwandelt. Ich habe es bis Billiarde geschaft aber ab Trillion kommt der Fehler "Das Numerische Ergebniss ist außerhalb des gültigem Bereiches".

Von hier aus weis ich nicht mehr weiter, hoffe ihr könnt mir weiterhelfen.

Hier ist mein Code

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
Code
#!/bin/bash

unter20() {

wert=$1
case "$wert" in

1)      echo -n "eins";;
2)      echo -n "zwei";;
3)      echo -n "drei";;
4)      echo -n "vier";;
5)      echo -n "fuenf";;
6)      echo -n "sechs";;
7)      echo -n "sieben";;
8)      echo -n "acht";;
9)      echo -n "neun";;
10)      echo -n "zehn";;
11)      echo -n "elf";;
12)      echo -n "zwölf";;
13)      echo -n "dreizehn";;
14)      echo -n "vierzehn";;
15)      echo -n "fünftzehn";;
16)      echo -n "sechszehn";;
17)      echo -n "siebtzehn";;
18)      echo -n "achtzehn";;
19)      echo -n "neunzehn";;
*)      echo -n "-Fehler-";;
esac    
}

zehner() {
wert=$1
case "`expr $wert / 10`" in
2)		echo  "zwanzig";;
3)		echo  "dreissig";;
4)		echo  "vierzig";;
5)		echo  "fuenfzig";;
6)		echo  "sechzig";;
7)		echo  "siebzig";;
8)		echo  "achtzig";;
9)		echo  "neunzig";;
*)      echo  "-Fehler-";;
esac
}

unter100() {
wert=$1
wert2=$1
if [ $wert -lt 20 ]
then 
unter20 $wert
elif [ `expr $wert % 10` != 0 ]
then
unter20 `expr $wert % 10` && echo -n "und" && zehner $wert2
else
zehner $wert2
fi
}

unter1000() {
wert=$1
wert2=$1
if [ $wert -lt 100 ]
then 
unter100 $wert
elif [ `expr $wert % 100` != 0 ]
then
unter20 `expr $wert / 100`
echo -n "hundert" 
unter100 `expr $wert2 % 100`
else
unter20 `expr $wert / 100`
echo -n "hundert" 
fi
}

tausend() {
wert=$1
wert2=$1
wert3=$1
if [ $wert -eq 1000 ]
then
echo "Tausend"
elif [ $wert -gt 1000 ] #Es sollte größer gleich sein MUSS NOCH ÄNDERN !!
then 
unter1000 `expr $wert / 1000`
echo -n "tausend"
fi
if [ `expr $wert3 % 1000` != 0 ]
then
unter1000 `expr $wert3 % 1000`	#warum musste ich eine neue variable wert3 #ansetzen??
fi
}

million() {
wert=$1
wertt2=$1
wert3=$1
mil=$wert
if [ $wert -lt 1000000 ] #Es sollte größer gleich sein MUSS NOCH ÄNDERN !!
then
tausend $wert
elif [ $mil -eq 1000000 ]
then
echo "eine Million"

else
mil=`expr $wert / 1000000`
unter1000 $mil
echo -n "Millionen"
wertt2=`expr $wertt2 % 1000000`
#echo "    $wertt2"
tausend $wertt2
fi
}

milliarde () {
wert=$1
wertt2=$1
wert3=$1
mil=$wert
if [ $wert -lt 1000000000 ] #Es sollte größer gleich sein MUSS NOCH ÄNDERN !!
then
million $wert
elif [ $mil -eq 1000000000 ]
then
echo "eine Milliarde"

else
mil=`expr $wert / 1000000000`
unter1000 $mil
echo -n "Milliarden"
wertt2=`expr $wertt2 % 1000000000`
#echo "    $wertt2"
tausend $wertt2
fi
}

billion () {
wert=$1
wertt2=$1
wert3=$1
mil=$wert
if [ $wert -lt 1000000000000 ] #Es sollte größer gleich sein MUSS NOCH ÄNDERN !!
then
milliarde $wert
elif [ $mil -eq 1000000000000 ]
then
echo "eine Billion"

else
mil=`expr $wert / 1000000000000`
unter1000 $mil
echo -n "Billion"
wertt2=`expr $wertt2 % 1000000000000`
#echo "    $wertt2"
tausend $wertt2
fi
}

billiarde () {
wert=$1
wertt2=$1
wert3=$1
mil=$wert
if [ $wert -lt 1000000000000000 ] #Es sollte größer gleich sein MUSS NOCH ÄNDERN !!
then
milliarde $wert
elif [ $mil -eq 1000000000000000 ]
then
echo "eine Billiarde"

else
mil=`expr $wert / 1000000000000000`
unter1000 $mil
echo -n "Billiarde"
wertt2=`expr $wertt2 % 1000000000000000`
#echo "    $wertt2"
tausend $wertt2
fi
}

trillion () {
wert=$1
wertt2=$1
wert3=$1
mil=$wert
if [ $wert -lt 1000000000000000000 ] #Es sollte größer gleich sein MUSS NOCH ÄNDERN !!
then
milliarde $wert
elif [ $mil -eq 1000000000000000000 ]
then
echo "eine Trillion"

else
mil=`expr $wert / 1000000000000000000`
unter1000 $mil
echo -n "Trillion"
wertt2=`expr $wertt2 % 1000000000000000000`
#echo "    $wertt2"
tausend $wertt2
fi
}



#Hauptprogramm
echo "Bitte Wert eingeben"
read wert
#unter20 $wert
#zehner $wert
#unter100 $wert
#unter1000 $wert
#tausend $wert
#million $wert
#milliarde $wert
#billion $wert
#billiarde $wert
trillion $wert

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Die maximal mögliche Größe von Zahlen in der Shell ist abhängig von der Architektur und der Implementierung - in der Bash auf einem 64-Bit System sind ist der maximale Wert heutzutage 2^63 -1 = 9223372036854775807, wenn man drüber geht, wird es etwas haarig - beim Rechnen gibt es einen Wrap-Around, wobei sich expr und $(()) interessanterweise teilweise unterschiedlich verhalten:

$ echo $(( 2 ** 63 -1))
9223372036854775807
$ echo $(( 2 ** 63))
-9223372036854775808
$ wert=9223372036854775808
$ expr $wert / 1000000000000000000
9
$ echo $(($wert / 1000000000000000000))
-9 

Und bei Vergleichen mit dem test-Konstrukt kann er den String nicht mehr als Zahl interpretieren, wenn er zu groß ist.

Als Workaround könnte man die Berechungen und Zahlen-Vergleiche mit bc machen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
if (( $(echo "$wert == 1000000000000000000" | bc -l) ))
then
    echo "eine Trillion"
elif (( $(echo "$wert >= 1000000000000000000" | bc -l) ))
then
    mil=$(echo "$wert / 1000000000000000000" | bc -l)
    unter1000 $mil
    echo -n "Trillionen"
    wertt2=$(echo "$wertt2 % 1000000000000000000" | bc -l)
    #echo "    $wertt2"
    tausend $wertt2
fi

oeztuerk_42

(Themenstarter)

Anmeldungsdatum:
19. Mai 2019

Beiträge: 25

ich muss das irgendwie mit String-Manipulation lösen ☹

Anhang

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4453

Hm, Du verwendest aber ja gar keine String-Manipulation.

Du könntest so etwas machen:

partnumber() {
    local index=$1;
    if [[ $length -ge $index ]]; then
        count=$index;
    else
        count=$length;
    fi
    if [[ $length -ge $index ]]; then
        part=3;
    else
        part=$(($index-$length+1));
    fi
    echo ${number:(-$count):$part};
}

number=23234574273263273;
length=${#number};
echo $(partnumber 18) Billiarden;
echo $(partnumber 15) Billionen;
echo $(partnumber 12) Milliarden;
echo $(partnumber 9) Millionen;
echo $(partnumber 6) Tausend;

Was hier noch fehlt, ist, dass partnumber nur aufgerufen werden darf, falls die Zahl überhaupt entsprechend groß ist. Und die Zahl vor dem Billiarden müsstest Du dann eben wieder durch die Funktion jagen, die Dir die Zahl in den entsprechenden String unwandelt.

Bis zu welcher Größe soll dieser Stringoutput denn funktionieren? Da könnte man dann natürlich noch einen Array mit Tausend, Millionen, Miliarden, Billionen, Billiarden, usw. definieren, wo man die ganzen Zahleneinheiten reinpackt.

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4453

So, das ganze nochmal mit dem Array, den ich erwähnt hatte:

#!/bin/bash

partnumber() {
	local index=$1;
	if [[ $length -ge $index ]]; then
		count=$index;
	else 
		count=$length;
	fi
	if [[ $length -ge $index ]]; then
		part=3;
	else
		part=$(($length-$index+3));
	fi
	echo -n ${number:(-$count):$part};
}

units=("Hundert" "Tausend" "Millionen" "Milliarden" "Billionen" "Billiarden" "Trillionen" "Trilliarden" "Quadrillionen" "Quadrilliarden");
number=85736272348574432587435987345;
length=${#number};

upto_unit=$((($(($length-1))/3)));

for i in $(seq $(($upto_unit+1)) -1 2); do 
	echo $(partnumber $(($i*3))) ${units[$(($i-1))]};	
done

EDIT: Moment, da ist gerade noch ein blöder Fehler in einem der Zähler drin...

EDIT: So, Skript ist korrigiert. Nun musst Du nur noch die Zahlen unter tausend nochmal entsprechend ersetzen. Und das Singular/Plural Problem bei den Einheiten lösen, aber dafür müsstest Du nur einen zweiten Array mit den entsprechenden Einheiten im Singular definieren, einen Check in die Funktion einbauen und dort die EInheit mit ausgeben lassen.

Antworten |