Diskuze: Zaokrouhlení hodnot
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 25 zpráv z 25.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Jestli potřebuješ zaokrouhlit číslo v kódu, jde to udělat tak, že double (float, nebo co používáš) vynásobíš 1000 a zaokrouhlíš klasicky pomocí Math.Round, potom vydělíš 1000 a máš to.
double cislo = 12.345678d;
cislo *= 1000; // 12345.678
cislo = Math.Round(cislo); // 12346
cislo /= 1000d; //12.346
Nebo, když se ti nechce psát zbytečně kód, mělo by jít:
Math.Round(cislo, 3);
Žádný z kódů jsem nezkoušel, může tam být chyba.
Díky za reakci, ale problém je, že mě ta hodnota chodí ve stringu, takže to nelze takto použít.
A nemohl bys to přeparsovat?
string s = "123.456";
double d = double.Parse(s); // 123.456
Já tu hodnotu potřebuju mít ve stringu, pac ta komunikace probíha pres tcp a ta hodnota je posílána jako řetězec:
public string readValue(string value)
{
string result = readVar(Socket, value);
double d = double.Parse(value);
Math.Round(d, 3);
return result;
}
Takze myslis, ze takhle by to mohlo fungovat?
Jestli to chápu správně, tak to máš skoro dobře:
string result = readVar(Socket, value);
double d = double.Parse(result); // je v result to cislo ve stringu? Jestli jo, parsuj result
d = Math.Round(d, 3);
result = d.ToString();
return result;
pokud bys nechtěl zaokrouhlovat, ale stačilo by ti jen odstranit přebývající znaky tak můžeš použít
string s = "12345.12345";
string x = s.Remove(s.IndexOf('.') + 4);
//nebo
string y = s.Substring(0, s.IndexOf('.') + 4);
//v obou pripadech bude vystup 12345.123
Nevím, co dostáváš v resultu, takže napíšu tohle:
string cislo = ...; // "123.456"
double d = double.Parse(cislo)
d = Math.Round(d, 3);
cislo = d.ToString();
return cislo;
Můžeš sem dát ukázku, co přesně obsahuje value z toho readVar(Socket, value); ?
to value obsahuje řetezec, kterým volám příslusnou hodnotu, např.: "$Max_weight" ...atd
Použij ten poslední kód co jsem ti poslal. Zjisti si, co to vrací to číslo ve stringu a použij to, mělo by to fungovat.
Jak to tak vidím tak nejdřív asi budeš muset z toho stringu vypreparovat to číslo samotné - nejlépe za pomocí regulárního výrazu - řekl bych dokonce, že ti číslo vrátí v požadovaném tvaru - ovšem bude to opět jenom oříznuté -ne zaokrouhlené
Příklad máš "tady ":https://regular-expressions.mobi/…ngpoint.html
Mohl bys nám prosím napsat přesně hodnoty všech proměnných? Máme v tom trochu zmatek.
EDIT: A rozhodni se, jestli chceš používat řešení moje (klasické zaokrouhlení), nebo ostrozana (usekne všechna desetinná místa až na tři). V určitých situacích ti bude každé řešení dávat jiný výsledek.
Zalezi jakym retezcem(instrukcí) je budu volat a ten dany retezec je presne
v te promenne value a vypada vzdy takto "$Max_value" apod., tech prikazu je
spousta...
Pokud jde o zpusob reseni, je mi to jedno, hlavne aby to fungovalo. I kdyz ten
ostrazana mi přijde lepší v případě nějakých jiných nevhodných znaků,
které se mohou vyskytnout na konci volaného řetězce.
Shrnu to jeste jednou: mam sadu nejakych instrukcí v tomto tvaru "$Max_value" ,
coz je ulozeno v promene "value", zalezi kterou vzdy zavolam, to se děje v
jiné tride např. takto: readValue("$Max_value") a to mi vrací tu mojí
žádanou hodnotu, kterou potrebuji zaokrouhlit. Tak možná jestli to
zaokrouhlování nepouzit az v te tride, kde ji volám?
Takže co vrátí readValue("$Max_value")? Třeba "12.345"?
Ostrozanovo řešení je lepší v tom co říkáš, má ale nevýhodu, a to, že nezaokrouhluje, jenom odsekává poslední část, takže tam budou v 50 % případů malé odchylky. Můžeš si je dovolit, nebo to je jenom pro zvýšení čitelnosti a už s tím číslem dál nepracuješ? Ale ať už použiješ jakékoli řešení, potřebujeme přesnou ukázku toho, co dostaneš z toho zařízení.
Co tedy přesně vrací metoda readVar(Socket, value); ? nějaký string ve
tvaru 12345.123456 - tedy textovou podobu floating point number?
nebo ještě i něco jiného - což vlasně připouštíš
případě nějakých jiných nevhodných znaků, které se mohou vyskytnout na konci volaného řetězce.
tady by ti pomohl ten regex - tady máš teda konkrétní příklad
Regex regex = new Regex(@"[-+]?([0-9]*\.[0-9]+|[0-9]+)");//vytahne pouze cislo s desetinnou teckou
Match match = regex.Match(readVar(Socket, value));
if (match.Success)
{
double d = double.Parse(match.Value)
d = Math.Round(d, 3);
return d.ToString();
}
toto je dobré když chceš vyseparovat nějaký vzor z textu třeba z "hledané číslo je 123.45" ti vytáhne "123.45"
tvůj případ by se dal ošetřit i jednodušeji použitím TryParse místo Parse ale to by ti výsledek v případě chyby zahodilo, což asi nechceš
petr: ano, treba toto: -25.49212 a ty poslední 2 znaky zatím nevím co jsou, takže to oříznutí by bylo asi lepší řešení. Ale, počet desetinných míst se liší, záleží jakou hodnotu přesně volám. To, že nezaokrouhluju tolik nevadí, ta přesnost na 2 des.místa je dostačující, takže si to dovolit mohu(ano, lepsi pro zvyseni citelnosti).
ostrozan: ano presne tak, nekdy to muze vratit např i text: FALSE, ne jen
číselne hodnoty..
Moc díky za příklad. V tom případě tohle řešení bude asi jediné z
možných, protože to co volám to NE VŽDY vrací číslené hodnoty, ale jak
jsem psal výše: i např. FALSE atd. a ještě za to ty zbytečné znaky .
Tak zkusím pak ten regex, slyším o tom úplně poprvé. Během příštího
týdne to vyzkouším, jestli to bude fungovat. Díky
ovšem profík by to napsal takhle
return match.Success ? Math.Round(double.Parse(match.Value), 3).ToString():"neplatné číslo";
Pěkné Já tohle nedělám od doby, kdy jsem spojil asi 4 ternární výrazy, 6 linq querin a potom jsem to za půl roku potřeboval upravit
Ale v tomhle případě mi to přijde i přehlednější ten ternární výraz
tak ono jako všude - i tady platí všeho s mírou nebo jak
se někde říká vocaď pocaď
ta moje ukázka je tak mez srozumitelnosti - dál už bych asi nešel
Zobrazeno 25 zpráv z 25.