Programistyczne WTF jakie Was spotkały

Programistyczne WTF jakie Was spotkały
adf88
  • Rejestracja: dni
  • Ostatnio: dni
0

Zamiast !!x zawsze można wymyślić coś czytelniejszego, zależnie od kontekstu mogłoby to być:

Kopiuj
x != 0
(bool)x
x != 0 ? 1 : 0

Nie przepadam za !!

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Java, fragment dokumentacji metody System.nanoTime()

The value returned represents nanoseconds since some fixed but arbitrary origin time (perhaps in the future, so values may be negative). The same origin is used by all invocations of this method in an instance of a Java virtual machine;

Zaobserwowany objaw:

Kopiuj
long startTime = System.nanoTime();
BigDecimal f2 = wyraz2(n);
long estimatedTime = System.nanoTime() - startTime;
System.out.println(estimatedTime); // -8279859

Dodam, że ujemne czasy pojawiają się tylko wtedy gdy czas wykonania jest bardzo krótki i nie za każdym razem. Częściej czas jest dodatni niż ujemny.

NE
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 29
0

Co wyświetli dla:
long end = System.nanoTime();
long elapsedTime = end - start;

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Liczbę ujemną.

NE
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 29
0

A tak:

long startTime = System.nanoTime();
BigDecimal f2 = wyraz2(n);
//tutaj niech poczeka z jedną sekundę
long estimatedTime = System.nanoTime() - startTime;
System.out.println(estimatedTime);

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Nie warto sprawdzać, funkcja wyraz2(n) liczy n-ty wyraz ciągu Fibonacciego korzystając ze wzoru Bineta. Interesował mnie czas wykonania dla dużych n, z głupia frant zmierzyłem dla małych, ujemne czasy pojawiają się tylko dla n<=3.

MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
0
bogdans napisał(a):

Java, fragment dokumentacji metody System.nanoTime()

The value returned represents nanoseconds since some fixed but arbitrary origin time (perhaps in the future, so values may be negative). The same origin is used by all invocations of this method in an instance of a Java virtual machine;

Zaobserwowany objaw:

Kopiuj
long startTime = System.nanoTime();
BigDecimal f2 = wyraz2(n);
long estimatedTime = System.nanoTime() - startTime;
System.out.println(estimatedTime); // -8279859

Dodam, że ujemne czasy pojawiają się tylko wtedy gdy czas wykonania jest bardzo krótki i nie za każdym razem. Częściej czas jest dodatni niż ujemny.
ale jak to się ma do cytowanej dokumentacji? Dokumentacja jedynie stwierdza, że czas zerowy nie musi się odnosić do konkretnego czasu bezwzględnego i czas zerowy nie musi się odnosić do przeszłości (zero może wypaść w przyszłości), więc to nie ma nic wspólnego z tym WTF.
Co do samego WTF to zrobiłbym coś takiego:

Kopiuj
long[] data = new long[1000];
for (int i=0; i<1000;++i)
    data[i] =  System.nanoTime();

To może naprowadzić co jest źle. http://ideone.com/IZdiy

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Przeczytaj wytłuszczony fragment dokumentacji.

Kopiuj
long[] data = new long[1000];
    for(int i=0;i<1000;i++)
        data[i] = System.nanoTime();
    for(int i=0;i<999;i++)
        if(data[i]>data[i+1])
             System.out.println(data[i]+" "+data[i+1]);
    for(int i=0;i<999;i++)
        if(data[i]>=data[i+1])
             System.out.println(data[i]+" "+data[i+1]);

Ekran jest pusty.

Olamagato
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Polska, Warszawa
  • Postów: 1066
0

Mi nigdy nie wyskakują ujemne wartości bo każdy sprzętowy licznik bitowy traktuję jako unsigned i nigdy się na tym nie przejechałem. Po prostu nigdy nie spotkałem licznika, który kręciłby się jak liczba ze znakiem.

Normalnie wystarczyłoby przepakować wartość ze znakiem do typu liczby o większej pojemności i wtedy odjąć, ale problem w tym, że dla long trzeba by użyć BigInteger, a nie jest to warte takiego poświęcenia. Szczególnie w przypadku System.nanoTime().

Najlepiej to sobie wyobrazić na przykładzie unsigned byte. Licznik kręci się od zera w górę, aż dojeżdża do bez-znakowej 128, które jest w arytmetyce ze znakiem interpretowane jako -128. Potem kręci się dalej i bez znaku osiągniemy 255, a ze znakiem -1. Następnie kręci się dalej i znowu będzie mieć 0 w obu arytmetykach. Czyli bez znaku będziemy mieli 0->255->0, a ze znakiem 0->127->(-128)->(-1)->0.
Do tego dochodzi jeszcze odejmowanie wartości późniejszej od wcześniejszej.
Może się zdarzyć, że arbitralnie trafiona pierwsza liczba będzie miała wartość unsigned a = 250, a następne trafienie unsigned b = 5.
Wynik 5 - 250 = 11 ponieważ w arytmetyce unsigned liczby są traktowane jako U2, więc będzie 5 - (-6) = 11. Co ciekawe kiedy liczba będzie interpretowana jako signed, to w tym jednym wypadku też będzie ok. Różnice pojawią się kiedy pierwsza wartość będzie 7-bitowa, a druga 8-bitowa. Na przykład unsigned a = 100, b= 130 (signed -126). W arytmetyce U2 wynik będzie 130 - 100 = 30, a w arytmetyce ze znakiem -126 - 100 = -26. W ten sposób dostaniemy liczby ujemne.
Jeżeli nie da się skonwertować liczb na większe wersje unsigned, a tak jest w Javie, to najprościej jest stracić dokładność na jednym najmniej znaczącym bicie. Oznacza to podzielenie obu stron różnicy przez 2 i pomnożenie wyniku przez 2, ale wynik nie zmieni się dopóki różnica będzie się mieścić w liczbie okrojonej z tego bita, czyli w przypadku typu long gdy różnica między pomiarami będzie mniejsza niż 129 lat. :)
Krótko mówiąc:

Kopiuj
long start = System.nanoTime() >> 1;
//...
long time = ((System.nanoTime() >> 1) - start) << 1;

Używam >> zamiast >>> bo nadal potrzebuję odejmowania z właściwym znakiem.

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
0

W notacji U2 liczby ze znakiem i bez znaku odejmuje i dodaje się tak samo. W asemblerze x86 istnieje tylko jedna instrukcja do dodawania intów i tylko jedna instrukcja do odejmowania.

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Chyba nie trafiłeś. Zmodyfikowałem nieco kod:

Kopiuj
        int counter = 0;
        for(int i=0;i<10000;i++)
        {
            start = System.nanoTime();
            BigInteger f2 = wyraz2(n);
            long end = System.nanoTime();
            if(end-start<0)
            {
                counter++;
                System.out.println("2. Czas wykonania (w nanosekundach): "+(end-start)+" (wzor Bineta)");
                System.out.println("Start: "+start);
                System.out.println("End: "+end);
            }
        }
        System.out.println(counter); //313

Liczby start oraz end były dodatnie.
Może ktoś ma ochotę sprawdzić czy jego komputer też jest bardzo szybki ;). U mnie czasu ujemne pojawiają się dla n <= 8

Kopiuj
    private BigInteger wyraz2(int n)
    {
        double pom = Math.sqrt(5);
        BigDecimal podstawa = new BigDecimal((1+pom)/2.0);
        BigDecimal potega1 = podstawa.pow(n);
        podstawa = new BigDecimal((1-pom)/2.0);
        BigDecimal potega2 = podstawa.pow(n);
        BigDecimal wynik = potega1.add(potega2.negate());
        return wynik.divideToIntegralValue(new BigDecimal(pom)).toBigInteger();
    }
bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Komputer jest taki szybki dla typów BigInteger i BigDecimal, po zmianach:

Kopiuj
...
long f2 = wyraz3(n);
...
private long wyraz3(int n)
{
    double pom = Math.sqrt(5);
    double podstawa = (1+pom)/2.0;
    double potega1 = Math.pow(podstawa,n);
    podstawa = (1-pom)/2.0;
    double potega2 = Math.pow(podstawa,n);
    double wynik = (potega1 - potega2)/pom;
    return (long)wynik;
}

ujemne czasy wykonania zniknęły.

  • Rejestracja: dni
  • Ostatnio: dni
0

Gdybyście czytali dokumentację, to dowiedzielibyście się, że działanie System.nanoTime() zależy od platformy na której leży Java. Wystarczy, że procek w międzyczasie podniesie taktowanie i już jest minus, ale to nie tylko to. Czy komuś na Linuksie pokazują się te ujemne czasy, czy to tylko domena Windowsa?

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Myśmy czytali, a nawet cytowali. Natomiast Twoja odpowiedź sprawia wrażenie, że dokumentacji jeszcze nie widziałeś, albo widziałeś i nie zrozumiałeś.

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
0

A czy tu jest coś niezgodnego z dokumentacją? Pojawiły się wam jakieś czasy, które są mniejsze niż czas początkowy?

Jeśli Java liczy czas jako różnica_wartości_rdtsc / aktualne_taktowanie to przy zmianie taktowania mogą dziać się różne kwiatki. Wyłącz turbo w procesorze czy tam wszelakie opcje zarządzania energią/ obniżania taktowania i wtedy odpal program.

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Jest.

The value returned represents nanoseconds since some fixed ... origin time
Więc dla późniejszego zdarzenia (wywołania funkcji) wartość musi być wieksza.

  • Rejestracja: dni
  • Ostatnio: dni
0

To chyba jakąś inną dokumentację macie

"Returns the current value of the most precise available system timer, in nanoseconds.

This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values may be negative). This method provides nanosecond precision, but not necessarily nanosecond accuracy. No guarantees are made about how frequently values change. Differences in successive calls that span greater than approximately 292 years (263 nanoseconds) will not accurately compute elapsed time due to numerical overflow. "

*so values may be negative

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
0

Spróbuj tego, jeśli masz źle załatanego XP: http://stackoverflow.com/a/3315836/492749
Na (chyba) Linuksie działa ok: http://ideone.com/PTA2X

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

@st, tę samą, tylko czytamy ją z większym zrozumieniem. Czasy mogą być ujemne, ale różnica czasów (zdarzenie późniejsze - zdarzenie wcześniejsze), nie może. Inna sprawa, że w cytowanym przykładzie czasy są dodatnie.

  • Rejestracja: dni
  • Ostatnio: dni
0

Genialna funkcja:

http://pastebin.com/Shzyta7p

Olamagato
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Polska, Warszawa
  • Postów: 1066
0

OMG. Jeżeli to jest z kodu produkcyjnego, to możliwe że ta firma już upadła. :)
Programiści powinni przechodzić "test lenia"...

  • Rejestracja: dni
  • Ostatnio: dni
0

Nie, to kod jednego z początkujących ;) Co nie zmienia faktu, że jest to jedno z większych WTF jakie widziałem :P

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Chcesz zobaczyć większe WTF, to dołóż wymaganie by w polu tekstowym predkoscc1 pojawiała się informacja o prędkości speedd z dokładnością do 0,01 w zakresie od 0 do 1000.

adf88
  • Rejestracja: dni
  • Ostatnio: dni
0

Dopisałem się w komentarzu, ale widzę, że tu rozmowa rozgorzała więc też wypowiem się na pierwszym planie.

Ktoś używa "sf::String" czyli jakaś biblioteka zewnętrzna czy własny typedef/klasy czyli już coś tam umie/powinna umieć ale nie korzysta z tej podstawy. Ja rozumiem, że skończona precyzja liczb zmiennoprzecinkowych może zaskoczyć ale konwersje tekst<->liczba ... ehhh, czuję żal i mi smutno (czas wskoczyć na "trochę chumoru" :D ).

hauleth
  • Rejestracja: dni
  • Ostatnio: dni
0

Może nie WTF, ale nazwa biblioteki oryginalna https://github.com/supki/biegunka

I potem

Kopiuj
save = withBiegunka (\db → merge db <$> install)
rincewind
  • Rejestracja: dni
  • Ostatnio: dni
0

W kodzie produkcyjnym podczas refaktoringu znalazem dwie dość ciekawe metody. Pierwsza z nich to getIntOrZero(), która zwraca int, a jako parametr przyjmuje obiekt requestu. W samej metodzie cay request jest walidowany (kolo 50 linii kodu), następnie dobiera się do pola id, które przyszo po GET z requestu, a następnie jeśli id == null to zwraca 0, w przeciwnym przypadku wartość. WTF-em jest wiele mówiąca nazwa metody.

Druga z metod to getNullOrLong(), zwracająca Long i również jako parametr biorąca request. Jak latwo się domyślić, też dokonuje walidacji, a następnie zwraca wartość pola parent_id, też z GET.

Johnny_Bit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Kielce
0

Denerwowanie klienta biznesowego - część kolejna, tym razem dokumentowanie zawiłości. Żeby uprościć: X - dostawca usług zewnętrznych i dokumentacji do ich obsługi, Y - dostawca oprogramowania biznesowego, w tym obsługi usług X, Z - firma która korzysta z oprogramowania Y do obsługi usług X.

Problem:
Z zapisuje do X miasto "Łódź", Y wywala się, twierdząc że X zwraca błąd.
Dialog:
Support Y mówi - to dziwne ale wygląda na to że X nie akceptuje znaków 'Ł', i 'ż', bo "Kraków" przeszło...
Support X (i dokumentacja X) - obsługujemy pełny UTF-8!
Z do X - czemu Kraków ok a Łódź nie?
X do Y i do Z - Błąd po stronie Y, niech zrobią zgodnie z dokumentacją i niech zwrócą Z koszty związane z błędem.
Po 3 miesiącach w te i z powrotem:
odp finalna X - Błąd jednak po naszej stronie, nie wiedzieliśmy że Ł i ź to znaki w obrębie UTF-8. Proszę uaktualnić oprogramowanie, teraz nasze usługi obsługują pełen alfabet łaciński rozszerzony i cyrylicę! Obsługa UTF-8 nie jest w planach na najbliższe wersje.

Czemu udało się rozwiązać? Okazuje się że jakaś "bardzo ważna firma z Rosji" chciała użyć X i nie mogła. Więc wymusili poprawkę... A ani Y ani Z nie mieli do gadania nic w tej sprawie...

Patryk27
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 13042
0

korzysta z podstawowych cin/cout

I pewnie nawet nie wie, że << to operator przesunięcia bitowego, a nie przypisania (or something) :D


Mi się przypomina natomiast kłótnia z nauczycielem, jak to twierdzi, że nauka Javy bez znania Ajaxa nie ma sensu :D 2 faile na raz.
KR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2964
1

Sorry, że po angielsku, ale chyba sopie przetłumaczycie - gadaliśmy ostatnio z kumplem z firmy o hadoopie i o tym jacy to gimnazjaliści go piszą, i tak przy okazji ktoś wrzucił opis fajnego wtf:

How Hadoop (http://hadoop.apache.org/) selects map tasks for execution on JVMs:
0. set up a new MR job

  1. realized there are 12 free map slots on a tasktracker - ready to serve 12 map tasks
  2. selected 12 data-local map tasks, so far good
  3. spawned 9 (wtf? but no error in logs) new child JVMs and assigned them 9 map tasks among those 12 selected
  4. 9 map tasks finished fine
  5. 9 slots free, selected next 9 tasks
  6. realized, we have too few JVMs, so spawned 3 new missing JVMs (the config says there should be 12, right?)
  7. *** forgot 3 tasks from the first wave were never sent to any JVMs *** and scheduled 9 new tasks on 9 out of 12 ready JVMs leaving 3 JVMs idle
  8. all other tasks finished
  9. hadoop is waiting for the 3 never started tasks from the first wave
  10. 2 minutes later it is still waiting...
  11. 5 minutes later it is still waiting and nothing happens...
  12. 10 minutes later timeout happens, log says something like "oh f*ck, we lost 3 tasks, restarting"
  13. job finishes fine, SUCCESS!!!

Smart, isn't it? :D

Tak to jest jak kod piszą dzieci, których ulubionym słowem kluczowym w Javie jest "synchronized" i myślą, że programowanie wielowątkowe / wieloprocesowe jest łatwe.

mychal
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Przedmonitorze Górne
0

MS korzysta z kiepskiego translatora:
wtfoffice.jpg

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.