singels Kody
Widzisz posty znalezione dla hasła: singels Kody
Temat: EXCEL 2000 - mały problem
Analizując przykład Microsoftu i porównując go z moim kodem zamieszczonym w
innym poście w tym wątku nasunęły mi się następujące wnioski, którymi chcę
się podzielić:
1) Okazuje się, że stosunek ColumnWidth (w ilościach zanków standartowych)
do Width (w punktach) dla danej komórki nie jest stały, jak początkowo mi
się wydawało, lecz jest uzależniony od szerokości kolumny. Przy czym na moim
komputerze wygląda to następująco:
- dla ColumnWidth mniejszych lub równych 1 stosunek jest proporcjonalny i
wynosi 1 / 9
- dla ColumnWidth większych niż 1 można zapisać: Width = (ColumnWidth - 1) *
5.25 + 9
Wartości te się nie zmieniają pomimo zmiany rozdzielczości ekranu czy zmiany
rodzielczości wydruku. Ciekawe czy na innych komputerach ten stosunek
zachowuje się tak samo?
2) W związku z powyższym mój kod przynosi błędne wyniki w przypadku
znacznego zmniejszenia lub zmniejszenia szerokości kolumny przez tą
procedurę. Można tą wadę zlikwidować stosując pętlę podobną do przykładu z
MS, przy czym wystarczy 3-krotna zmiana szerokości kolumn, aby uzyskać
prawidłowy wynik.
3) Co ciekawe przykład z MS też niezbyt dobrze ustawia szerokośc kolumn,
szczególnie dla małych szerokości kolumn. Wynika to z załozenia przez
programistę mniejszej dokładności obliczeń, w związku z czym zmienne:
points, lowerwidth, upwidth, curwidth są typu Integer, a nie Single czy
Double.
4) Wreszcie zrozumiałem jak Excel zaokrągla szerokości kolumn: po prostu
szerokość kolumny jest wielokrotnością 0.75 pkt - tak przynajmniej zachowuje
się na miom koputerze.
5) Paweł Durys ma rację co do tego, że szerokości kolumn na różnych
komputerach czy innych drukarkach może być różna. Lecz wydaje mi się że wina
leży nie w odpowiednim przeliczeniu lecz po stronie programu. Np. rysując
linię prostą w Excelu i ustawiając jej długość na 6 cm otrzymuję na mojej
drukarce linię 6,3 cm. Podobnie jest np. z marginesami na stronie: mam górny
margines ustawiony na 2,5 cm, a na wydruku wychodzi 2,4 cm. O dziwo margines
lewy na wydruku ma tyle ile jest ustawione czyli 2 cm. W Wordzie nie ma aż
takich różnic.
Pozdrowienia
Temat: przetwornik AC
Witam niżej zamieszczem kod programu który przynajmniej teoretycznie miał
uruchomić przetwornik AC w trybie single conversion mode niestety nie
wygląda to tak jak miało ;) a miało wyglądać tak: Stworzyłem sobie funkcje
przerwania SIGNAL(SIG_ADC) ta funkcja powinna się uruchamiać po każdej
konwersji, niestety nie uruchamia się ani razu, jej uruchomienie spowodowało
by zapalenie się diody na czas 0,5s. Konwersje uruchamiają linijki kodu:
outp(0,ADMUX);
outp((1<<ADEN)|(1<<ADSC)|(1<<ADIF)|(1<<ADIE),ADCSR);
sei();
Przepisałem je słowo w słowo z przykładu z dokumentacji AVR_GCC według mnie
program ten powinien działać ale jakoś tego nie widzę ;). Niżej zamieszczam
kompletny program który nie działa. Co więcej zauważyłem że po komędzie
sei(); program tak jakby nie powracał z przerwania bo jeśli po tej komędzie
chce mignąć raz diodą czyli diode(1) to dioda zapala się ale nie gaśnie !!!
także coś tu jest naburaczone ;( a funkcja mrugania jest na pewno dobra bo
mrugałem nią nie raz ;) także coś tu jest nie tak. Proszę o pomoc.
Pozdrawiam
#define __AVR_ATmega8__ ;
#include <avr/io.h
#include <avr/delay.h
#include <avr/signal.h
#include <avr/interrupt.h
void diode(int im);
void sleep(int ms);
SIGNAL(SIG_ADC)
{
diode(1);
}
void sleep(int ms)
{
for (int l=0;l<ms;l++)
{
_delay_loop_2(4000);
}
}
void diode(int im)
{
sbi(DDRD,4);
for (;im!=0;im--)
{
cbi(PORTD,4);
sleep(500);
sbi(PORTD,4);
}
cbi(DDRD,4);
}
int main(void)
{
outp(0,ADMUX);
outp((1<<ADEN)|(1<<ADSC)|(1<<ADIF)|(1<<ADIE),ADCSR);
sei();
// diode(1) jeśli tu wywołam tą funkcje to działa nieprawidłowo (dioda
zapala się ale nie gaśnie a powinna zgasnąć po 0,5s). Opisywany przypadek
jednak zakłada że nie ma tu tej instrukcji wtedy dioda w ogóle się nie
zapala a powinna bo funkcja diode(1) wywoływana jest w funkcji przerwania.
while(1);
return(0);
}
Temat: zabić wątek i uruchomione w nim zapytanie
podziałałem, ale czeka mnie chyba głębsza analiza mechanizmów
regulujących działanie wątków.
Obecnie, jeśli wybiorę rekord na master i trwa realizacja zapytania,
po czym zmienię rekord na master - w detail zostaną podstawione dane
poprzednio zaznaczonego rekordu :(
Pierwsze zaznaczenie uruchamia wątek (zajmuje on query), a drugi
wystartowany później wątek ma zablokowany dostęp do query ?
A propo TQuery w wątkach: czy TQuery w wątku używa tej samej sesji do
główny wątek? Bo jeśli tak, to nie ma po co używać wątków, BDE i tak
będzie synchronizować wywołania wszystkich obiektóe związanych z jedną
sesją.
Żeby obiekty bazodanowe działały niezależnie w wątku, każdy wątek musi
mieć osobną sesję.
Z helpa Delphi:
Multi-threaded applications must create and maintain one additional
session component for each simultaneous connection to a single
database server.
Druga sprawa: Nie używaj Synchronize() do otwierania TQuery w wątku.
Synchronize() działa tak że wysyła komunikat CM_EXECPROC do głównego
wątku, i czeka na jego obsłużenie. Główny wątek wykonuje przekazany kod
funkcji.
Otwieraj TQuery normalnie, a w Synchronize() ewentualnie zgłaszaj
głównemu wątkowi że dane już czekają.
Możesz też mieć problem z bezpośrednim używaniem TQuery z wątku w
głównym wątku. VCL ma w wielu miejscach mutexy, BDE także, i jest
możliwy deadlock. Dlatego wszelkie operacje na wątkowym TQuery związane
z GUI musisz wykonywać z głównego wątku (bezpośrednio lub via
Synchronize()).
Tu jest artykuł o wątkach i DB:
http://www.delphicorner.f9.co.uk/articles/db1.htm
Temat: DBGrid i obliczenia
| Jak umieszczac w DBGrid obliczenia
| tzn wykonuje w jednej z procedur obliczenia np.:
| M1:=M2*M3; gdzie M1,M2,M3: Extended;
| label1.caption:= 'M1- '+floatToStrf(M1, ffExponent, 7, 3);
| i jak je zapisac w DBGrid aby mialy te sama forme
| tzn uzyskuje M1 - 1,2342E-001 i zeby je w stawic w identycznej formie
do
| tabeli
to moje
aha chodzi mi nie tylko o to zeby mialo taka sama forme ale w jaki sposob
to
zapisac to do DBGrida
| [ciach]
| Dodaj do tablicy pole Calculate
hmm Calculate i co dalej?????
--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
{CIACH}
A to kawałek z Helpa
po utworzenia nowego pola typu Calculate musisz wpisać kod do tabelki
OnCalculate
<<Cytat
"After you define a calculated field, you must write code to calculate its
value. Otherwise, it always has a null value. Code for a calculated field is
placed in the OnCalcFields event for its dataset.
To program a value for a calculated field:
1 Select the dataset component from the Object Inspector drop-down list.
2 Choose the Object Inspector Events page.
3 Double-click the OnCalcFields property to bring up or create a CalcFields
procedure for the dataset component.
4 Write the code that sets the values and other properties of the calculated
field as desired.
For example, suppose you have created a CityStateZip calculated field for
the Customers table on the CustomerData data module. CityStateZip should
display a company's city, state, and zip code on a single line in a
data-aware control.
To add code to the CalcFields procedure for the Customers table, select the
Customers table from the Object Inspector drop-down list, switch to the
Events page, and double-click the OnCalcFields property.
The TCustomerData.CustomersCalcFields procedure appears in the unit's source
code window. Add the following code to the procedure to calculate the field:
CustomersCityStateZip.Value := CustomersCity.Value + ', ' +
CustomersState.Value + ' ' + CustomersZip.Value;
Note
When writing the OnCalcFields event handler for an internally calculated
field, you can improve performance by checking the client dataset's State
property and only recomputing the value when State is dsInternalCalc. See
Using internally calculated fields in client datasets for details.<< Koniec
Cytatu
Temat: Soundex i język polski
[...]
to ten caly system moze i jest ciekawym pomyslem, ale obecnie mozna go o
kant stolu potluc.
Np.:
ts, tz, and tc were coded as a single code (the same as the letter s).
Te dzwieki to bardziej brzmia jak c niz s, ale np. w jezyku angielskim c
chyba nie istnieje.
Poza tym, np. nazwisko Czajkowski czasem sie zapisuje jako Tzaikowski, a
przeciez nalezaloby bardziej jako Chaaykovskee. Slowem- tylko posiadacz
danego nazwiska wie jak nalezy wymawiac jego nazwisko, ale nawet on moze
je wymawiac inaczej, niz jego pradziadowie. I kto wowczas ma racje- on,
jego pradziadowie, a moze tworca Soundexa? :
I właśnie dlatego szukam algorytmu lepiej przystającego do brzmienia i zasad
wymowy w języku polskim.
Nie sadze, zeby idealny system tepu Soundex mozna bylo stworzyc.
Idealnego na pewno nie da się zrobić. Oryginalny Soundex i jego modyfikacje
tworzone są pod kątem języka angielskiego. Wspomniany przeze mnie w
pierwszym liście Daitch-Mokotoff Soundex Coding lepiej odpowiada specyfice
języków słowiańskich ale jemu też wiele brakuje - był projektowany z myślą o
wyszukiwaniu nazwisk żydowskich.
Próbowałem raz sam wymyślić odpowiedni algorytm. Zasada jest stosunkowo
prosta - zlepki liter brzmiące podobnie koduje się tym samym kodem. Na
przykład w języku polskim literę "b" na końcu wyrazów czyta się jako "p",
litery "t" i "d" często czyta się tak samo itd. Jest wiele takich reguł. Ja
wiem o niektórych. Szukałem informacji o takich zasadach w sieci, ale
niestety nie znalazłem.
Przydałby się jakiś polonista z przynajmniej podstawową znajomością zasad
programowania.
Temat: Wyjatek EZeroDivide i krytyczny wyjatek
[...]
| Witam!
| Sprawdzałem na Delphi 3.0, Pentium 200 i Windows ME. Działa zgodnie z
| oczekiwaniami. Jak zmieniam flagę koprocesora (Set8087CW(Default8087CW
or
| $0004)) to dostaje wynik -INF.
Moge prosic o szczegoly ?
[...]
Witam!
Niestety nie ma ich zbyt wiele. Kiedyś zajmowałem się funkcją Round i
realizacją przez nią zaokrąglania. Z materiałów wynikało że można zmienić
flagę koprocesora aby zmienić jej zachowanie. Niestety z prób wynika że
żaden sposób nie odpowiada potrzebą polskiej księgowości. O dziwo chyba
wszystkie
te flagi są opisane w Delphi 5 Vademecum Profesjonalisty - Suplement w
rozdziale zmiany w RTL. Pomoc skieruje do instrukcji procesorów Intel. Takie
zmiany to są na pewno od Delphi 3, a może nawet od 2. W każdym razie w
jedynce .exe z Delphi można było rozpoznać bo kompilator się podpisywał, w
wyższych wersjach z tego że w module System jest procedura ładująca wartość
FPUMaskValue z klucza HKLMSOFTWAREBorlandDelphiRTL. Jest też funkcja w
Delphi do zmiany tych flag oraz zmienna przechowująca poprzednią wartość
flag ustawianych za pomocą tej funkcji. Jeśli chcemy zmienić flagi
powinniśmy przechować ich poprzednią wartość, nową ustawić i przywrócić
poprzednią po zakończeniu.
Są trzy kategorie flag:
- Tryb zaokrąglania
$0000 - zaokrąglanie do najbliższej parzystej (połówkowe) (domyślne)
$0400 - zaokrąglanie w dół
$0800 - zaokrąglanie w górę
$0C00 - ucięcie (w kierunku zera)
- Dokładność obliczeń
$0000 - Single
$0200 - Double
$0300 - Extended (domyślne)
- Maskowanie błędów numerycznych
$0020 - maskowanie błędu niedokładności wyniku (domyślne)
$0010 - maskowanie błędu niedomiaru (domyślne)
$0008 - maskowanie błędu nadmiaru (domyślne)
$0004 - maskowanie błędu dzielenia przez zero (domyślne)
$0002 - maskowanie błędu zdenormalizowanego argumentu (domyślne)
$0001 - maskowanie błędu niedozwolonej operacji
O ile się orientuje to maskowanie błędu oznacza że zostanie wywołane
przerwanie które proces powinien obsłużyć i zakończyć wyjątkiem EDivByZero.
W kodzie wyłączyłem taką możliwość i dlatego wynikiem jest minus
nieskończoność.
Wszystko fajnie tylko wątpię czy jakoś przybliżają Ciebie te wszystkie
informacje do rozwiązania problemu.
P.S. Kopia poszła na privo.
Temat: jak ruszyć obiekt ,okno, po okręgu ....
Witam
Proste,ale nie dla mnie pytanie.
Jak sprawić aby poruszać coś (np.okno aplikacji) po okręgu.
Może trzeba wykorzystać jakiś wzór matematyczny? Nie chodzi mi
o metodę przysuwania obiektów (np.okien) ale jak uzyskać x,y (lub wysokość
lub
szerokość monitora)potrzebne do przesuwania obiektów? Może jakiś kod
programu?
Tak, trzeba wykorzystać wzór matematyczny, kolejne współrzędne muszą się
jakoś wyliczyć, a bez wzoru to by był chyba problem, prawda ? ;-)
Myślę, że najlepiej w tym przypadku skorzystać nie ze znanego wzoru na
okrąg [ (x-sx)^2 + (y-sy)^2 = r^2 ], tylko z czegoś, co nam poda bezpośrednio
obie współrzędne dla każdego kolejnego kąta. Poniżej gotowa procedurka, którą
najlepiej sobie podczepić pod jakiś TTimer. Mam tylko nadzieję, że nie
przepiszesz tego bezmyślnie, ale będą z tego jakieś efekty i w przyszłości
podobne problemy już rozwiążesz sam.
-----------------------------------------------------------------------------
procedure TForm1.Timer1Timer(Sender: TObject);
var sx,sy,r: Integer;
kat: Single;
x,y: Integer;
begin
// współrzędne środka okręgu, po którym będziemy sobie "latać"
sx := (Screen.WorkAreaWidth - Width) div 2;
sy := (Screen.WorkAreaHeight - Height) div 2;
// promień okręgu - żeby nie wychodzić poza ekran wybieramy albo sx albo sy
if (sx < sy) then r := sx else r := sy;
// ustalenie aktualnego kąta - wykorzystamy sobie własność Tag
// naszego timera, która będzie określała kąt w stopniach
kat := Timer1.Tag / 180 * Pi;
Timer1.Tag := Timer1.Tag + 1;
// nowe współrzędne formy
x := Round( sx + r * sin(kat) );
y := Round( sy - r * cos(kat) );
// przestawienie formy
SetBounds(x, y, Width, Height);
end;
-----------------------------------------------------------------------------
pozdr. Yankee
Temat: Dynamic scoping in C++
A możesz podać jakiś przykład (nawet opisowo) kiedy to jest istotnie
wygodne.
Trudno o porywające przykłady. Przekazywanie kontekstu jawnie jest
tylko trochę mniej wygodne, użycie zmiennej globalnej zwykle uchodzi
na sucho, a wybór techniki zaczyna mieć znaczenie dopiero w dużych
programach. Dynamicznie wiązane zmienne pozwalają połączyć ogólność
i bezpieczeństwo jawnego kontekstu z wygodą zmiennych globalnych.
- Logowanie: przekazanie informacji, gdzie i jak logować problemy.
- Reakcja na asynchroniczne zdarzenia (np. na ^C i inne sygnały Unixa
tudzież przycisk Cancel). W tym stwierdzenie, czy dany fragment kodu
jest w ogóle przerywalny z zewnątrz, czy też trzeba pozwolić mu się
dokończyć.
- Tam, gdzie pojawia się przymiotnik "bieżący", np. dokument, nad
którym użytkownik pracuje, serwer, do którego połączony jest teraz
nasz klient, albo użytkownik, w imieniu którego działamy.
Wiele pojęć Unixa działa na zasadzie podobnej do dynamicznie wiązanych
zmiennych, tzn. każdy proces ma swoje, domyślnie dziedziczy się dla
procesów potomnych, można podmienić na inne: zmienne środowiskowe,
bieżący katalog, stdin/stdout/stderr, zalogowany użytkownik, ulimit,
chroot, zbiór blokowanych sygnałów itp.
A wiesz czy kompilatory potrafią to dobrze optymalizować?
Zależy, co w tym kontekście znaczy 'dobrze'. O ile wiem, zazwyczaj
wątek zawiera tablicę bieżących lokalnych "wiązań" zmiennych
indeksowanych "nazwami" zmiennych, a główna (domyślna, toplevelowa)
wartość zmiennej jest pamiętana w samej zmiennej. Jeśli lokalne
wiązania nie bywają uwspólnione między wątkami, to wątek może od
razu zawierać tablicę lokalnych wartości zmiennych.
W Kogucie dla prostoty implementacji wątek ma listę, a nie tablicę
zmiennych (ogony takiej listy łatwo się uwspólnia). Może kiedyś to
zmienię.
kiedy napiszesz lepszy tutorial? :-D
Nie wiem niestety.
I drugie pytanie: jak z obsługa socketów?
Jest prawie cała funkcjonalność gniazdek z Single Unix Specification.
Nie ma gotowej obsługi żadnych protokołów wyższych warstw.
Temat: klucz instalacyjny?
Wybitnie uzdolniony(a)
Nie, nie bedzie to prosba o podanie klucza do windowsa ;) Szukam
szybkiego sposobu na sprawdzenie jaki wpisalem klucz przy instalacji
windowsa 98/me/2000/xp Podejrzewam ze jest to gdzies zapisane w
rejestrze ale gdzie? Drugie pytanie dotyczy tego jak zmienic ten numer?
Czy wystarczy prosta podmiana w rejestrze czy cos jeszcze?
Start/ uruchom i wpisz
%systemroot%system32oobemsoobe.exe /a,teraz wybierz:
activate by phone (aktywacja przez telefon).
następnie Change Product Key (Zmień Kod Produktu)
Teraz wpisz nowy CDKEY i kliknij na update.
Zamykasz okno, restartujesz komputer .
Po wejsciu do systemu ponownie w okieno uruchom wpisz:
%systemroot%system32oobemsoobe.exe /a --dalej sobie poradzisz.
lub pomoże Ci programiki XPPID.exe,
WindowsXP Product Key Viewer.exe
http://kamileq.lava.pl/ftp/WindowsXP_Product_Key_Viewer.exe
oraz
Retrieve - view - change XP serial number! One single utility Magical
Jelly
Bean Keyfinder." Znajdziesz w dowolną wyszukiwarką. Programik odczytuje i
pozwala
zmienić "CD Key" Ms WindowsXP, 2003...
Natomiast dla dla W98 i ME:
HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersion
"ProductId" = xxxxxxxxxx (numer wygenerowany)
"ProductKey" =xxxxxxxxxxx (numer seryjny z "pudelka")
"RegisteredOrganization"= Firma
"RegisteredOwner"= Uzytkownik
Możesz tego ręcznie dokonać lub wykasuj te dwa pierwsze wpisy i restart
komputera, przy ponownym uruchamianiu dostaniesz okienko identyczne jak
przy
pierwszej instalce do wpisania numeru seryjnego.
plus zawartość USER.EXE i string BOULAMITE :
www.computer-investigations.com/arts/tech03.html
Temat: arkusz zalezny od podanej liczby
Witam!
witam,
mam taki maly problem
dotyczace powiedzmy sprzedazy dla roznej ilosci firm
czyli bedzie to wygladalo tak:
klikamy na button start i pojawia sie pytanie dla ilu firm mamy to
liczyc (to juz zrobilem)
no i teraz w zaleznosci od tej liczby musimy zbudowac arkusz, w ktory
bedzie mozna wpisac dane
(to tez juz mam)
dla 2 firm wyglada to tak:
jan feb mar ...
firma 1
firma 2
dla trzech oczywiscie p prostu dodajemy nowy wiersz
no i teraz trudny fragment: w kolejnym wierszu chce miec sume dla
kazdego miesiaca - jak to zrobic?
problem sprowadza sie do tego ze vb nie potrafi przerobic takiego
kodu:
ActiveCell.FormulaR1C1 = "=SUM(r[-x]c,r[-1]c)"
gdzie x to liczba firm zadeklarowana na poczatku
Spróbuj:
ActiveCell.FormulaR1C1 = "=SUM(r[-" & x & "]c,r[-1]c)"
problem ma zapewne z r[-x] ale nie wiem jaki i dlaczego, bo x jest
zdefiniowany jako single i tak chyba powinno byc
Mam tez pytanie jak zaznaczyc obszar w zaleznosci od x - np
zaczynajacy sie w a1 a konczacy w kolumnie m i o x w dol
probowalem range("a1: "m" & x") ale to jest zle moze jakos przez
cells? tylko ze nie wiem jak :(
Range("a1:m" & x).select
Z tym, ze bedzie to poprawne jezeli zaznaczasz od 1 wiersza. Gdy nizej,
nalezy zwiekszyc x czyli: x = x+pierwszy_wiersz_danych-1
na sam koniec chce wiedziec jak okreslic liczbe serii w wykresie w
zaleznosci od zmiennej x - no bo chce wyniki przedstawiac na wykresach
i beda sie zmienialy w zaleznosci od podanej na poczatku wartosci
Musisz zastosowac zródlo danych oparte na dynamicznym obszarze, zaleznym od
zmiennej x. Takie obszary definiuje sie tworzac nazwe (menu
Wstaw/Nazwa/Definiuj) odwolujaca sie do formuly, np.:
=PRZESUNIECIE($A$1;0;0;$N$1;12)
(gdzie $N$1, to przykladowa komórka przechowujaca wartosc zmiennej x)
Nazwe podajesz jako zródlo danych wykresu.
Tajan
Temat: Szesciobitowy zapis liczb (?!)
| BYTE (1bit)
| INTEGER (2 bity)
| SINGLE (4 bity)
| LONG (8 bitow)
| i inne, ale wsrod nich nie ma 6 bitowych. Przypuszczam, ze jakis inny
jezyk
| programowania stosuje zapis 6 bitowy. Moze ktos zna strukture tego innego
| zapisu, albo wie, jak zrobic konwersje?
chlopie! Zacznijmy od tego - Ty to wogole wiesz czym sie rozni bit od bajtu
?
pomysl:
No tak ktos koledze wreszczie wyjasnil ze pomylil bity z bajtami....
bit moze przyjmowac 2 wartosci : 1 albo 2.. A bajt ma 256 roznych mozliwych
wartosci - od 0 do 255..
Bit moze przyjmowac watosci 1 albo 2 .....no coz oby tak dalej fakt wtedy
mozliwosci jest 256 ale przyjmuje warotosci od 255 do chyba cos ponad 500 i to
z "dziurami"
Otoz BIT dordzy nowicjusze jest to inaczej pojednycza cyfra ukladu
dwojkowego(czyli o podstawie 2) w ktorym moga wsytepowac jedynie wartosci
0(zero) i 1(jeden)
Bajt jest to "paczka" 8 bitow.
A jezeli ten format ma faktycznie 6 bajtow ( bo na 6 bitach to minut i sekund
razem zadny msposbem nie da sie zapisac), to mozey byc to zapis w formacie
BCDna kazdej polwce bajtu jest zapisana liczba 0-9 w formacie dwojkowym.
np zapis 12:30:49 (g:m:s) moze wygladac w sytemie szesnastokwym tak
49h,30h,12h lub 12h,30h,49h ...
6 bajtowy (nie bitowy) to jest na przyklad zapis realow w pascalu..
W C++ float'y maja po 4 bajty.. Na koprocesorze (x87) masz mozliwe
(4,8,10)-cio
bajtowe floaty..
A tak pozatym - do wlasnego wykorzystania, jesli zalezy Ci na kodzie to
najlepiej nie uzywac zapisu zmiennoprzecinkowego, bo to dla procesora
bardzo
czasochlonne.. Fixed point to podstawa.. Jak kogos to interesuje to moge mu
to wytlumaczyc. To jednak odpada przy bardziej dokladnych obliczeniach.
--
Temat: umiejętności programisty
| Czemu uwazasz, ze to banialuki?
Moze niezbyt subtelnie, ale usiluje podac w watpliwosc sensownosc podzialu
programistow na super i zwyklych na podstawie tempa produkcji
oprogramowania. To dlatego, ze to bardzo sliskie kryterium podzialu.
Cytat:
[CUT]
The studies that measured programmer productivity were based on giving the
same specification to a large group of programmers, and recording the amount
of time they took, among other metrics such as defects and lines of code.
It was common to find differences of 10X between the time taken by the upper
quintile and lowest quintile, sometimes even as high as 20X.
Unfortunately, there isn't any long-term similar study because of the
expense; these things typically took place in a single day or a weekend.
But that kind of productivity difference can be imprecisely observed in the
real world - look at some pieces of software produced by a small company.
If you had a similar sized set of average or poor programmers and gave them
10X the amount of time, would they be able to produce it? Or could 10X the
number of programmers produce it in the same time?
Doom for example, was written by only 3 or 4 programmers. A set of 30, or
even 300 average programmers could not create it.
[/CUT]
A pod tym adresem znajdziesz tego wiecej:
http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPos...
3
Hmmm, jesli to wynika z tekstu, ktory zamiescilem to moze przeczytaj go
jeszcze raz. Zaczyna sie od ozdobnika, ktory sugeruje inny podzial
programistow (to ten kawalek z 'tak naprawde'), i nastepnie nazywa ten
A, czyli stwierdziles, ze programisci piszacy 5-55 razy szybciej kod nie
wiedza co robia. I stwierdziles to na podstawie jakis badan, czy tez
zdrowego rozsadku, na podstawie ktorego opierali sie ludzie twierdzacy, ze
ziemia jest plaska?
pozdrawiam
Merlin
Temat: Access -> MSSQL
Hello Jacek,
| Czyli jaki? Wybierz z poniższych.
| Access: byte, integrer,long integrer, single, double, decimal
| SQL: bigint, float, decimal, int, smallint, numeric, tinyint
JSSmoze tez byc problem z tym, ze w Accesie liczby dziesietne
JSSsa z kropka a w MS SQL z przecinkiem ( lub na odwrot ).
To też nie to - poprzedni mail sądzę jest bliżej - w MSSQL jest to ty
pola Numeric, w Accesie jest to typ liczba - liczba całkowita długa
(long integer) i są to liczby właśnie całkowite do określania pozycji.
Dostałem z innego źródła że może być to spowodowane przypisaniem
danych numerycznych do zmiennej która mósi być zadeklarowana.
W kodzie forum w którym występuje tenże komunikat błędu - wygląda to
tak:
If objForumCountRS.Fields("forum_id") = objForumRS.Fields("forum_id") Then Exit Do
i tutaj w przypadku korzystania z MSSQL występuje błąd "type
mismatch". tylko dlaczego jeżeli trzeba okreslić typ zmiennej dla
danych numerycznych pracuje to poprawnie z plikiem Accessa ? ;)
Sugerowana poprawka mówi o przeformatowaniu tychże zmiennych w
postaci:
If cInt(objForumCountRS.Fields("forum_id")) = cInt(objForumRS.Fields("forum_id")) Then Exit Do
Zaraz sprawdzę czy to faktycznie rozwiąże problem - czeka mnie troszkę
kopania po nieswoim skrypcie i zmian ;) Zna ktoś prawdopodobne
przyczyny takiego zachowania przy odczycie danych z MSSQL ? czy może
być to powodowane zwracaniem przez sterownik OLEDB danych o typie
czysto tekstowym, nie jak przez sterownik Accessa który obsługuje
wszystie typy ? (jak się domyślam, od niedawna się bawię ASP)
Dziękuję wszystkim za odpowiedzi - jak nie pomogą to chociaż naprowadzą na właściwą
drogę ;)
Temat: Unix vs Linux
| Czy komercyjne Uniksy nadal pod jakimikolwiek względami są lepsze od
| Linuksa, czy może jest wręcz przeciwnie - obecnie Linux wygrywa i to
| producenci systemów komercyjnych uprawnieni przez The Open Group do
| nazywania ich Uniksami czerpią z niego wzorce? Czy Linux Standard Base
| staje się specyfikacją, do której wszyscy dążą, a Single UNIX
| Specification
| powoli traci na znaczeniu? Czy to Uniksy obecnie ewoluują w stronę, którą
| wyznacza Linux, a nie odwrotnie? Co o tym sądzicie?
Linux niemalże jako całość jest zbitkiem kodu powstałego w inspiracji
systemami komercyjnymi (czego nikt się wcale nie wypiera). A ponieważ
czerpano i _porównywano_ z różnych systemów, Linux jest systemem łączącym
(co najmniej w teorii) najlepsze cechy tych systemów.
Teza, jakoby porownywano rozne rozwiazania, nie ma kompletnie zadnego
zwiazku z rzeczywistoscia. Chyba, ze efekty porownan ladowaly w koszu.
Od samych poczatkow systemu poczawszy - az do wersji 2.6 Linux nadal
uzywal rozwiazan, ktorych komercyjne systemy pozbyly sie dziesiec lat
wczesniej, np. sposobu buforowania danych dyskowych - poprzez
implementacje sendfile(2), ktore nie potrafi samo doczepic naglowkow
przed wyslaniem danych, co wymaga uzywania dodatkowego write(2), tudziez
linuksowego devfs-a, ktory byl tak broken by design, ze dziwic sie mozna,
ze w ogole go wlaczono do kernela, az po... Zdania nie dokoncze, bo nie
sledze rozwoju Linuksa, wiec nie wiem, jakie rozwiazania wybieraja teraz.
Ale sposob rozwoju, w szczegolnosci Linusowe 'code speaks louder than
words', sie nie zmienil, wiec podejscie do myslenia i przedyskutowania
A czy systemy komercyjne mimo wszystko są lepsze? Porównaj sobie Solarisa z
Linuxem na Sparcu...
To porownanie nawet na nie-sparcu daje efekt sprzeczny z twoja teza - o ile
wydajnosc obu rozwiazan jest podobna, o tyle pod wzgledem dostepnosci
oprogramowania czy bezpieczenstwa Linux jest mocno w tyle.
Temat: Dodawanie wielu rekordow z jednego formularza - mozliwosci
Pawel Durys:
Zastanawiam sie aktualnie nad najlepszym sposobem dodawania kilku rekordow z
jednego formularza.
Projektuje tabele, ktora bedzie przechowywac wyniki serii pomiarow. Kazda
seria moze miec od 1 do 12 wartosci. Serie pomiarow sa (jak na razie) dla
trzech roznych wielkosci fizycznych.
Struktura tabeli tblPomiary jest trywialnie prosta:
ID - Autonumer 'przechowuje numer serii pomiarowej
typ - byte 'przechowuje kod wielkosci (jak na razie 1, 2 lub 3)
pomiar - byte 'numer pomiaru od 1 do 12.
wartosc - single 'wlasciwa wartosc danego poamiaru
Poniewaz liczba pomiarow dla serii moze byc rozna, wiec kombinuje z
formularzem, ktory ma grupe opcji (jak na razie trzy) i 12 (slownie
dwanascie) pol tekstowych dla poszczegolnych pomiarow.
Po wpisaniu pomiarow naciska przycisk cmdSave i zapisuje do tabeli
tblPomiary wyniki - tyle rekordow ile pomiarow.
Jak na razie mam pomysl:
For i=1 to 12
varP = Me("txtP" & i).Value
If Not IsNull(varP) Then
If IsNumeric(varP) Then
DoCmd.OpenQuery "INSERT INTO..."
...
Next i
Macie inne propozycje?
Może formularz z podformularzem?
Tabela [Serie]:
[IdSerii] (Autonumer)
[IdWielkosci] (jeśli dobrze zrozumiałem, seria obejmuje pomiary jednej wielkości)
... (np. DataGodzina)
Tabela [Wielkosci]:
[IdWielkosci] (Autonumer)
... (np. Nazwa, JednostkaMiary)
Tabela [Pomiary]:
[IdSerii]
[NrPomiaru]
[Wartosc]
Formularz główny oparty na tabeli [Serie], podformularz oparty na tabeli [Pomiary],
pole łączące [IdSerii].
Temat: Word Translator
Oto co program WordTranslator potrafi zrobić z opisem pewnego programu
(tłumaczenie z angielskiego):
Prezentacja programu TestStand
<cite
Narodowy Instrumenty TestStand zamierza automatyzować szeroko rozumiane
problemy. Wprost z pudełka, TestStand jest gotowy podjąć się próbie
kierowania, organizowania, kontrolując, i wykonując twój automatyzowany
prototyp, lub produkcyjny problem systemowy. TestStand jest w zupełności
nastrajalny, tak że ty możesz modyfikować i dopasowywać go do twoich
specyficznych potrzeb. [...]
W dodatku, TestStand może korzystać z dynamicznej linii bibliotek ( Dll
), ActiveX Serwer, lub Exe tak by łatwo można popierać wieloraką próbę
programującą otoczenie jak również istniejący kod zapisu. [...]
TestStand dostarcza najnowsze osiągnięcia {przedstawieniu} które ty
potrzebujesz. Bardzo szybki próbny rozwój i bardziej rozumne dane.
Używanie 32 bitowych, szybkobieżnych, wielotorowych maszyna {silnik}
zdolna jest z biegu równolegle wykonywać wiele zadań. TestStand bardzo
pomaga, ty próbujesz więcej, a produkt bardziej szybki.
</cite
A teraz możliwości programu:
<cite
Usuwanie błędów z programu
Breakpointsl/single krokowe wykonanie
Variable displaysl/watch okno interakcyjny próbne wykonanie
Interakcyjny próba robiąca pętlę
Nastrajalne Informowanie
[...]
Automatyczna następstwo dokumentacja
Następstwo Redagujący
Wyciąć i wklei
wlecz się i spadaj
^^^^^^^^^^ROTFL^^^^^ (to jest, gdyby ktoś nie wiedział, drag&drop)
</cite
Jeśli chcecie to mam jeszcze tego trochę...
Temat: Czy tylko ja mam problem z procedurami w argumentach makra?
Muszę się przyznać do niedoinformowania ...
procedura Function może robić dokładnie to samo co Sub, a oprócz tego zwraca
wynik poprzez swoją nazwę do WYRAŻENIA.
W przykładzie z poprzedniego maila w Sub MultiplyEm można słowo kluczowe Sub
zamienić na Function i efekt będzie ten sam.
Funkcja więc też może zwracać wartość przez swoje argumenty !!!
Czyżby więc trzeba się zgodzić że ograniczenie argumentu akcji UruchomKod do
funkcji nie ma sensu ?
Ogólnie rzecz biorąc TAK.
Jedyne usprawiedliwienie, to to, że w przypadku Sub zwracanie wartości przez
argumenty jest regułą,
a w wypadku funkcji regułą jest zwracanie tejże poprzez swoją nazwę.
Ale ryzyko wykorzystania funkcji przez nie zadeklarowaną zmienną pozostaje
to samo ...
Cóż, mimo wszystko o coś swoją wiedzę wzbogaciłem ...
Krzysztof Naworyta
Ale się uparłeś...
A i ton listów staje się coraz mniej przyjemny ...
Ale jednak dokończę swoją myśl (Dlaczego procedury nie mogą być argumentem
w
akcji "UruchomKod")
Otóż procedura jest tworem bardzo elastycznym. W porównaniu z funkcjami
potrafi dużo więcej, a jedynie czego nie potrafi, to zwrócić wartości do
wyrażenia (czy to zewnętrznego w obiektach Access'a, czy też bezpośrednio
w
kodzie).
W kodzie oczywiście można to obejść.
Przedstawię teraz przykład procedury i sposób jej wywołania (pochodzi on z
podręcznika "VB dla aplikacji w przykładach")
Sub MultiplyEm(Value1 As Single, Value2 As Single, Produkt As Single)
Produkt=Value1 * Value2
End Sub
Procedura ją wywołująca:
Sub TestProc()
Dim Result As Single
MultiplyEm 5, 7, Result
MsgBox Result
End Sub
krótki komentarz:
Co robi pierwsza procedura każdy widzi: mnoży pierwszy argument przez
drugi
i zwraca poprzez zmienna Produkt.
Co robi druga ? Ot, po prostu wyświetla wynik.
Ale zwróć uwagę: na to aby ten wynik otrzymać, należało uprzednio
zadeklarować zmienną Result.
Konkluzja: czy potrafisz zadeklarować zmienną w makrze ?
Uprzedzając Twoją ripostę - przykład jest trywialny, łatwo go obejść
wykorzystując Function zamiast Sub.
Ale w przypadku ogólnym Subrutyna może mieć postać daleko bardziej
skomplikowaną.
A Ty jako twórca skomplikowanego kodu możesz w końcu zapomnieć przez które
zmienne przekazujesz parametry do środka, a przez które wyciagasz wynik
(jeśli w ogóle)
to tyle
pozdrawiam
| No cóż, jak ktoś nie wie co to są argumenty ByRef w procedurze ...
| Sub JakasSub(A1 As integer, A2 As integer, A3 As integer)
| 'domyślnie ByRef
| A1=A1 + 10
| A2=A2 + A1
| A3=5
| end sub
| Jak myślisz, co zwraca ta procedura ?
| Otóż zwraca obrobione A1, A2 i A3, a funkcja/procedura, która ją
wywołała,
| może je dalej przetwarzać.
| To nieprawda (patrz niżej), a poza tym co to ma do poprzedniego listu???
| cytat z "Migrating from C++ to VB" - może uściśli termin "zwracać
| wartość"
| : In VB, functions without a return value are called subroutines and are
| declared with a Sub keyword:
| ^^^^^^^^^^^^^^^^^^^^^^
| :
| : Sub PrintReport
| : End Sub
| :
| : Functions that return a value are called functions.
| Proponuję czytać posty zanim klikniesz Reply
| [in10d]
Temat: Czy tylko ja mam problem z procedurami w argumentach makra?
Ale się uparłeś...
A i ton listów staje się coraz mniej przyjemny ...
Ale jednak dokończę swoją myśl (Dlaczego procedury nie mogą być argumentem w
akcji "UruchomKod")
Otóż procedura jest tworem bardzo elastycznym. W porównaniu z funkcjami
potrafi dużo więcej, a jedynie czego nie potrafi, to zwrócić wartości do
wyrażenia (czy to zewnętrznego w obiektach Access'a, czy też bezpośrednio w
kodzie).
W kodzie oczywiście można to obejść.
Przedstawię teraz przykład procedury i sposób jej wywołania (pochodzi on z
podręcznika "VB dla aplikacji w przykładach")
Sub MultiplyEm(Value1 As Single, Value2 As Single, Produkt As Single)
Produkt=Value1 * Value2
End Sub
Procedura ją wywołująca:
Sub TestProc()
Dim Result As Single
MultiplyEm 5, 7, Result
MsgBox Result
End Sub
krótki komentarz:
Co robi pierwsza procedura każdy widzi: mnoży pierwszy argument przez drugi
i zwraca poprzez zmienna Produkt.
Co robi druga ? Ot, po prostu wyświetla wynik.
Ale zwróć uwagę: na to aby ten wynik otrzymać, należało uprzednio
zadeklarować zmienną Result.
Konkluzja: czy potrafisz zadeklarować zmienną w makrze ?
Uprzedzając Twoją ripostę - przykład jest trywialny, łatwo go obejść
wykorzystując Function zamiast Sub.
Ale w przypadku ogólnym Subrutyna może mieć postać daleko bardziej
skomplikowaną.
A Ty jako twórca skomplikowanego kodu możesz w końcu zapomnieć przez które
zmienne przekazujesz parametry do środka, a przez które wyciagasz wynik
(jeśli w ogóle)
to tyle
pozdrawiam
| No cóż, jak ktoś nie wie co to są argumenty ByRef w procedurze ...
| Sub JakasSub(A1 As integer, A2 As integer, A3 As integer)
| 'domyślnie ByRef
| A1=A1 + 10
| A2=A2 + A1
| A3=5
| end sub
| Jak myślisz, co zwraca ta procedura ?
| Otóż zwraca obrobione A1, A2 i A3, a funkcja/procedura, która ją
wywołała,
| może je dalej przetwarzać.
To nieprawda (patrz niżej), a poza tym co to ma do poprzedniego listu???
cytat z "Migrating from C++ to VB" - może uściśli termin "zwracać
wartość"
: In VB, functions without a return value are called subroutines and are
declared with a Sub keyword:
^^^^^^^^^^^^^^^^^^^^^^
:
: Sub PrintReport
: End Sub
:
: Functions that return a value are called functions.
Proponuję czytać posty zanim klikniesz Reply
[in10d]
Temat: techniki szyfrowania.. kodu
Chcialbym uniemozliwic odczytanie mojego algorytmu nieporzadanej
osobie. Oczywiscie zakladam, ze potencjalny zlodziej ;) zna doskonale
assembler i potrafi zdekompilowac moj program (zajmuje on zaledwie
kilka kb). Nie piszcie tylko, ze jest to niepotrzebne - mi jest :) Nie
piszcie tez, ze jest to niemozliwe - w kazdym razie DA SIE chyba
bardzo utrudnic odczytanie takiego kodu?
Zwykly xor mozna bardzo latwo odxorowac, tak samo bedzie z wiekszym
wzorkiem... Po prostu procedura deszyfrujaca bedzie przeciez
deszyfrator (po prostu przepisac procedure..). Szukam wiec jakiegos
innego sposobu - nie plynnego zamienienia ciagu bajtow, lecz.. czegos
innego.. ale czego?
Czy macie jakies pomysly?
Poza jakimis zlozonymi procedurami szyfrujacymi sprobuj wstawic
mnostwo upierdliwych detali, ktore beda zniechecaly do single
stepow i wykonywania kodu po kawalku. Polecam dosc prymitywne
sposoby, ale jesli sie tego duzo nawstawia, to strasznie wkur,
no, irytuje i meczy tego, kto to bedzie lamal.
* sprawdzanie, czy cos przejelo single step. Jesli tak, to cos
nieprzyjemnego (LOCK LOCK HLT, albo skok w losowe miejsce pamieci,
INT 18h etc)
* wykonywanie sobie czesto INT 03
sposob):
przejmujesz single-step, podstawiajac pod niego procedurke.
wlaczasz single-stepping, najlepiej jakos tajemniczo (np. kladziesz
flagi na stos, dwa kilo kodu dalej zmieniasz w tych na stosie
bit odpowiedzialny za single step, dwa kilo kodu dalej, w proce-
durze, ktora np. czeka na vertical retrace zdejmujesz flagi ze
stosu). Od tego momentu co kazda twoja instrukcje odpala sie
procedurka, ktora wisi na single-stepie. W hackpl'u, jesli dobrze
pamietam, mieli kod, ktory zmienial inny kod. Jesli bedziesz to
wykonywal pod np. Turbo Debuggerem, to rozszyfrowywanie nie bedzie
sie wykonywalo i jak juz dojdzie do szyfrowanych instrukcji,
wszystko padnie.
* Wywolaj pare razy niepotrzebne odwolania do INT10, INT21.
To rozwali rzeczy typu UNP.
* Rozdmuchaj kod bzdetami, potem spakuj go PKLITem, LZEXE i UCEXE
po kolei (rozdmuchujac za kazdym razem, zeby sie dalo pakowac).
Pozniej pogrzeb tak, zeby UCEXE sie nie polapal i nie mogl odpakowac
EXEka, bo ktos Ci go odpakuje. Wstaw tez troche bzdur, zanim bedzie
sie odpalala procedura rozpakowujaca.
* Umieszczaj krytyczne partie (rozkodowujace, szukajace TD itp)
w jakichs glupich miejscach (procedury czekajace na klawisz,
scrolling (albo cos co go udaje, jesli ci niepotrzebny :)).
* Podlacz sie pod timer i sprawdzaj, czy nie ma w pamieci TD,
czy cos innego nie przejelo INT 01 (nie wszyscy uzywaja TD :),
itd. itp.
* Na koniec wszystko zaxoruj, zaxoruj z kluczem, ktory sie zwieksza
o 1 co bajt, pozniej jeszcze czyms prostym, ale duzo tego wpieprz.
* Zgadzam sie z kims w poprzednich postach, ze trzeba wstawic duzo
bzdur. Wez jakies poprzednie programy (najlepiej jakies procedury
kodujace, beda wygladaly podejrzanie!) i wlacz je w miejsca,
ktorych nie uzywasz. Z glownego programu rob skoki, ktore beda
trafialy na RET/RETFy w tych procedurach.
Ogolnie, moim zdaniem, najlepiej isc "na chamowe" i poprostu nalozyc
mnostwo smieci, ktore zajmuja duuuzo czasu czlowiekowi, aby sie
przez to przegryzc.
Temat: strukturalnie/obiektowo D3/D5/D7 - inny kompilator???
Miałem obliczenia strukturalne, które po przerobieniu na wersję obiektową
spowolniły działanie (w pokazanym przykładzie około 10%) tzn na moim kompie
zmiana z 4.4 sek na 5 sekund. Przekompilowałem ten sam kod testowo 5 i 7 i
okazało się, że i strukturalnie i obiektowo liczy się około 4.9 sekundy
(bardzo powtarzalnie, obiektowo około 1% wolniej). Jestem niemal pewien, że
optymalizację mam ustawiona wszędzie tak samo. W związku z tym dlaczego tak
sie to zmieniła szybkośc pracy? Pierwsze podejrzenie to takie, że teraz
wszystko jest obiektowo (w sensie wszystkie procedury i zmienne globalne są
polami i metodami jakiegos globalnego obiektu i przy okazji optymalizator
jest troche lepszy).
Czy ktoś miał już takie doświadczenia? O co tu chodzi?
W tym konkretnym przypadku, który Pan zamieścił jako przykład,
to wszystko może rozbijać się o 1 instrukcję: a[i, j] := s, a dokładniej,
o sposób wyznaczania adresu efektywnego, pod który należy zapisać
wynik, a ten jest mocno zależny od miejsca zadeklarowania zmiennej 'a',
ilości wolnych rejestrów i działań optymalizatora.
Proponuję zakomentarzować następną linikę
if (j mod 2 = 0) then s:=s/2 else s:=s*2;
bo jest ona identycznie liczona w obydwu przypadkach
(operuje tylko na zmiennych lokalnych), a z powodu
użycia zmiennych typu single jest znacznie bardziej
czasochłonna od całej reszty kodu i tylko zaciemnia
wyniki testów.
Po takim zabiegu okaże się, że kod "obiektowy" jest 3 razy
wolnieszy od kodu "strukturalnego" na każdej wersji Delphi,
a przyczyną jest właśnie sposób wyznaczania adresu efektywnego
dla każdego elementu tablicy. Usuwając jedną linijkę obliczeń z
wnętrza pętli prawdopodobnie dla wersji "strukturalnej" zwolniliśmy
jeden rejestr i optymalizator mógł go wykorzystać do szybszego
wyznaczania adresu efektywnego dla kolejnych elementów tablicy.
Szczegóły do obejrzenia przez View-Debug Window-CPU.
Wersja "obiektowa" prawie zawsze będzie potrzebowała jednego
rejestru więcej do przechowania adresu bazowego obiektu (Self),
względem którego adresuje poszczególne pola obiektu i optymalizator
ma mniejsze pole do popisu.
Jeśli moje rozważanie są prawidłowe, to nasuwa mi się jeden wniosek:
W Delphi 3 optymalizator był bardziej wyrafinowany niż w Delphi 5 i 7
i potrafił nawet bez zakomentarzowanej linijki obliczeń na liczbach Single
zorganizować efektywniejszy zapis kolejnych elementów tablicy, ale
chodziły też wtedy słuchy, że działanie optymalizatora może w pewnych
sytuacjach prowadzić do błędów w obliczeniach i być może to właśnie
zostało poprawione w kolejnych wersjach Delphi poprzez wyeliminowanie
pewnych zbyt wyrafinowanych działań optymalizatora.
Temat: Delphi7 i graphics32
tej pory cały czas w visual c++ 6 i net, visual basic 6, java to nie jest
łatwo w ciagu tygodnia poznac delphi.
Ee... nie przesadzajmy. Najwiekszym problemem bedzie chyba poznanie
srodowiska. VB i Java w sumie sa dosc podobne do Delphi...
My mamy tak, że często robimy na zajęciach dla prowadzących rzeczy o których
im się gdzieś kiedyś przyśniło i sami nie mają dokładnego pojęcia co chca i
jak to ma wyglądać. Ale cóż przecież to możliwe tylko w Polsce że np
matematyk uczy grafiki komputerowej....
Wogole sie na ten temat nie wypowiem...
Zaś trzecia obraca bitmape i nawet chyba dobrze działa, ale ma jeden błąd -
po obróceniu bitmapy o jakis kąt na nowej bitmapie pojawiaja sie czasami
(dosyc czesto) piksele które nie zostały tak jakby uzupełnione kolorem -
poprostu czasne kropki. Może któś naprowadzi mnie jak pozbyć sie tego
problemu...
Nie jestem grafikiem i do tej pory nie zajmowałem się tym więc wybaczcie mi
moją prostote tego kodu.
<ciach
Jesli nie znasz srodowiska to wklejam Tobie ponizej kod procki
obracajacej BitMape... Aczkolwiek jesli tej grafiki uczy matematyk to
moze mu sie nie spodobac ze sam tego nie liczysz, tylko zwalasz to na
biblioteke GR32_Transformations ;) Ale w sumie miales jej uzywac? nie?
oto kod troszeczke szybszy(dzialajacy program znajdziejsz w katalogu
gdzie zainstlaowales GR32 w podkatalogu Exaples program Rotete_EX):
procedure TForm1.ScaleRot(Alpha: Single);
var
SrcR: Integer;
SrcB: Integer;
T: TAffineTransformation;
Sx, Sy, Scale: Single;
begin
SrcR := Src.Bitmap.Width - 1;
SrcB := Src.Bitmap.Height - 1;
T := TAffineTransformation.Create;
T.SrcRect := FloatRect(0, 0, SrcR + 1, SrcB + 1);
try
T.Clear;
T.Translate(-SrcR / 2, -SrcB / 2);
T.Rotate(0, 0, Alpha);
Alpha := Alpha * 3.14159265358979 / 180;
Sx := Abs(SrcR * Cos(Alpha)) + Abs(SrcB * Sin(Alpha));
Sy := Abs(SrcR * Sin(Alpha)) + Abs(SrcB * Cos(Alpha));
Sx := Src.Bitmap.Width / Sx;
Sy := Src.Bitmap.Height / Sy;
scale := Min(Sx, Sy);
T.Scale(Scale, Scale);
T.Translate(SrcR / 2, SrcB / 2);
Dst.BeginUpdate;
Dst.Bitmap.Clear(clGray32);
Transform(Dst.Bitmap, Src.Bitmap, T);
Dst.EndUpdate;
Dst.Repaint;
finally
T.Free;
end;
end;
pozdrawiam,
Przemek O.
Temat: Czy jest gdzieś po polsku?
Witam, skorzystałam z adresu, który ktoś podał w poprzednim poście-
http://validator.w3.org i sprawdziłam tam stronkę, nad którą biedzę się od
jakiegoś czasu (już tu była o niej mowa www.maranta.neostrada.pl). Wypisało
mi tam oczywiście masę błędów, czego się spodziewałam. Jednak mam pytanie,
czy jest gdzieś możliwość sprawdzenia swojej strony i otrzymania wyników po
polsku??? Angielski znam tylko potoczny. Tutaj połączenie nieznanego mi
HTML-a i zagmatwanej angielszczyzny nie ułatwia mi zadania. Wyniki jakie mi
pokazało są tu:
http://validator.w3.org/check?uri=http%3A%2F%2Fwww.maranta.neostrada.pl
tylko nie wiem jak je wykorzystać. Z translatora wolę nie korzystać, bo
zgłupieję do reszty.
Line 14, column 21: value of attribute "NAME" must be a single token
<meta name="Microsoft Theme" content="none, default"
Wartość atrybutu "NAME" musi być pojedyńczym wyrażeniem - chodzi o
to, że między Microsoft a Theme nie powinno być spacji. Bład
kosmetyczny, cały tag nie ma żadnego praktycznego znaczenia poza
informacyjnym. Moja rada - usunąć całość.
Line 15, column 21: value of attribute "NAME" must be a single token
<meta name="Microsoft Border" content="none, default"
Jak poprzednio.
Line 17, column 29: required attribute "TYPE" not specified
<script language="JavaScript"
The attribute given above is required for an element that you've
used, but you have omitted it. For instance, in most HTML and XHTML
document types the "type" attribute is required on the "script"
element and the "alt" attribute is required for the "img" element.
Typical values for type are type="text/css" for <styleand
type="text/javascript" for <script.
Chodzi o to, że powinien być podany atrybut "TYPE", którego nie
podałaś. Prawidłowo:
<script language="JavaScript" type="text/javascript"
Line 61, column 90: an attribute value must be a literal unless it contains only name characters
..t="208" align="left"style=filter:Glow(Color=lightyellow,strength=10)</i</fo
Zdaje się tutaj czepia się nawiasu. Cos mi się widzi, że automat
błednie zinterpretował cały ciąg jako wartość atrybutu "align".
Spróbuj tego miedzy "left" a style wstawić odstęp:
align="left" style=...
Line 61, column 121: required attribute "ALT" not specified
..r:Glow(Color=lightyellow,strength=10)</i</font
Zabrakło atrybutu "alt". Spróbuj:
..r:Glow(Color=lightyellow,strength=10) alt="jakis tam
tekst alternatywny"</i</font
Tak na marginesie - deklarujesz (wiem, że nie Ty, tylko program, ale
używając go godzisz się na wyniki jego pracy, tym samym jakbyś brała
za nie odpowiedzialność.) wygląd tekstu tagiem "<font". To czysty
bezsens bo żadnego tekstu w tym nie ma. Wyjasniam po kolei:
<font color="#FFFFCC" face="Comic Sans MS"- Kolor i krój czcionki
<i- Pochylenie tekstu
<img border="0" src="maranta1v.gif" width="150" height="208"
align="left" style=filter:Glow(Color=lightyellow,strength=10)
Tu wstawiasz obrazek
</i- zamykasz tag pochylenie
</font- zamykasz tag tekstowy.
Po co to wszystko?
Przy okazji wyjaśnienie - w Mozilli tego rozświetlenia nie widać
również (bo to przypada akurat w tym miejscu). To jakiś microsoftowy
wynalazek, nie umieszczony w standardach. Będzie widoczny tylko w IE.
I tak dalej, i tak dalej...
Sporo widzę tam poszatkowanego kodu, który dodatkowo ogłupia automat
walidujący.
I jeszcze jedno. Do niektórych obrazków na stronce, spróbowałam dodać efekt
poświaty- gdzieś w necie znalazłam odpowiedni kod. Jednak jest to widoczne w
IE a w Operze już nie. Czemu? I gdyby ktoś mógł rzucić okiem jak jest z tą
sprawą w Mozilli.
Już wyjaśniłem wyżej
Pozdrawiam, A.
Proszę, tylko nie mówcie, że jak się tak na niczym nie znam, to po co się za
to biorę. Po prostu chcę się czegoś nowego nauczyć a cieszę się z każdej
drobnej rzeczy, która mi jako tako wyjdzie ;)
:)
Nmie zastanawia inna rzecz - jak ktoś dłubie we Frontpejdżu to zwylke
nie zawraca sobie głowy walidatorami, to już wyższa szkoła jazdy.
Skąd u Ciebie ten pomysł?
I na koniec rada - zainstaluj Mozillę, jest tam też bardzo przyjemny
edytorek HTML, który produkuje znacznie czystszy kod. Powodzenia.
PS. Tak wiem, nudzi mi się, spać nie mogę. ;)
Temat: Cos wolne te Maczki ...
Te testy nie byly optymalizowane pod AltiVeca, coz moze wiec wynikac z testu
wykorzystujacego 25% mocy obliczeniowej procesora. To jakas lamerka.
Bo nie mogły być optymalizowane pod AltiVec'a.
Dlaczego ?
AltiVec technology:
? Meets the computational demands
of networking infrastructure such as
echo cancellation equipment, and
basestation processing.
? Enables faster, more secure encryp-tion
methods optimized for the
SIMD processing model.
? Provides compelling performance
for multimedia-oriented desktop
computers, desktop publishing, and
digital video processing.
? Enables real-time processing of the
most demanding data streams
(MPEG-2 encode, continuous
speech recognition, real-time high-resolution
3D memory for 3D
graphics.)
Do tego generalnie służyć ma AltiVec.
Czyli obliczenia na liczbach w najlepszym przypadku zmiennoprzecinkowych z
pojedyńczą precyzją. Do grafiki, obróbki wideo itp. zastosowań to wystarcza.
A do liczania "zmiennegoprzecinka z podwójną dokładnością" to G4 ma osobny
koprocesor numeryczny który niema nic wspólnego z AltiVeciem ...
? Floating Point Unit
? Support for IEEE-754 standard single and double precision floating point
arithmetic
? 5 cycle latency, 1 cycle throughput, single or double precision
multiply-add
? Hardware divide
? Hardware support for denormalized numbers
? Table lookup for reciprocal square root estimate instruction
? Early out divide iteration for reciprocal estimate instruction
? Time-deterministic non-IEEE mode
A to troszkę bliżej o AltiVecu
AltiVec technology is a short vector parallel architecture.
Depending on data size, vectors are 4, 8 or 16 elements long.
This can be contrasted with the long vector architectures of
supercomputers that were popular in the 1980s. Vector sizes
for those machines ranged to hundreds of elements. The long
vector approach of supercomputers, while useful for scien-tific
calculations, is not optimal for the communications,
multimedia and other performance-driven applications tar-geted
by Motorola with AltiVec technology.
AltiVec technology operations are performed on multiple
data elements by a single instruction. This is often referred
to as SIMD (single instructions, multiple data) parallel pro-cessing.
AltiVec technology offers support for:
? 16-way parallelism for 8-bit signed and unsigned integers
and characters,
? 8-way parallelism for 16-bit signed and unsigned integers
? 4-way parallelism for 32-bit signed and unsigned integers
and IEEE floating-point numbers
AltiVec technology can be most accurately thought of as a
set of registers and execution units added to the PowerPC
architecture in an analogous manner to the addition of float-ing
point units. Floating point units were added to most
mainstream microprocessor architectures several years ago
to provide better support for high-precision scientific calcu-lations.
AltiVec technology is being added to the PowerPC
architecture to dramatically accelerate the next level of per-formance-
driven, high-bandwidth communications and
computing applications
Cytaty pochodzą z oficjalnych materiałów Motoroli.
Wystarczy poszperać chwilę po www.motorola.com :
Czyli panowie, bez jaj. G4 to dobry i szybki procesor dla urządzeń
telekomunikacyjnych i komputerów pracujących z aplikacjiami multimedialnymi.
I w tym jest naprawdę dobry, pod warunkiem zoptymalizowania kodu programu.
A ile jest takich programów, bo w Photoshopie to raptem kilka
nienajprzydatniejszych filtrów ?
Ale obiczenia numeryczne to nie jest jego silna strona.
Nie dam sobie nic obciąć ale FPU w G4 niewiele się różni od tego w G3 ...
Oto wyniki testów syntetycznych podanych przez Motorolę
dla G4
dla G3:
Szczerze mówiąc wysłałem tego posta na wabia,
by zobaczyć jak z fanatyzmem religijnym na grupie.
Jak widzę ... nieźle.
Miłego dnia wszystkim :)
Amen
Temat: Szybki sinus - naiwne pytania ;)
Na starym Pentium 166 MHz obliczenie sinusa trwa
0.6 mikro (10^-6) sekundy w single i 0.8 mikrosekundy w double.
Mysle, ze uzycie wprost funkcji sinus nie bedzie najwolniejsza czescia
Twojego programu.
B52
Na początek może krótki opis "tła" problemu.
Ostatnio zainteresowałem się zagadnieniami związanymi z DSP
i syntezą dźwięku. W wielu przypadkach wymagane jest tam
szybkie (i w miarę dokładne) obliczanie wartości funkcji
trygonometrycznych, szczególnie sinusa (jako najbardziej
podstawowej funkcji). I ten problem mnie również ostatnio
nurtuje :) Piszę na razie drobny kawałek kodu w C,
staram się w miarę możliwości unikać schodzenia do poziomu
asemblera (bo kod ma być przenośny).
Z przyczyn wydajnościowych odpada funkcja biblioteczna
sin(double). Nie nadają się tutaj również tradycyjne
podejścia matematyczne, w rodzaju wzoru Maclaurina, bo
ich implementacja w C również jest zbyt wolna (trzeba
obliczyć co najmniej 6-7 wyrazów szeregu, by otrzymać
wynik z zadowalającą precyzją). Zostaje więc chyba
jedyna sensowna metoda - "lookup table", czyli wcześniejsze
obliczenie wyników dla określonej liczby argumentów
(tutaj można skorzystać z funkcji bibliotecznej ;)),
a następnie interpolowanie wartości między tymi punktami.
Może fragment kodu:
int TABSIZE = 4096; // wielkość LUT (lookup table)
float sampleRate = 44100.f; // tak, to częstotliwość próbkowania CD ;)
float c = sampleRate / TABSIZE;
float TWOPI = 2 * 3.1415926;
// liczymy na floatach, bo taka precyzja nam wystarcza
float mysin(float x) {
float res;
// "zmiennoprzecinkowy indeks" do tabeli
float f = x * sampleRate / (TWOPI * c);
// część całkowita, czyli indeks właściwy
int index = (int)f;
index %= TABSIZE;
if (index == f) {
res = tab[index];
} else {
float dx = f - index;
res = tab[index] + dx * (tab[index+1] - tab[index]);
}
return res;
}
Jak widać, na razie stosuję interpolację liniową, która nie jest
we wspomnianych zastosowaniach zbyt dobrym pomysłem, ale można
to trochę zrekompensować wielkością tabeli (im gęściej rozłożone
punkty, tym większa szansa, że interpolowana wartość będzie bliska
oczekiwanej). W ten sposób udało mi się uzyskać przyspieszenie
sięgające w porywach 2 razy w porównaniu z funkcją sin.
No to teraz pytania:
1) Czy ktoś zna inny, lepszy sposób rozwiązania problemu?
2) Czy powyższy kod da się zoptymalizować w znaczący sposób?
3) Czy zna ktoś dokładniejszą metodę interpolacji, ale o zbliżonej
wydajności?
Będę wdzieczny za wszelkie wskazówki
Paweł
Temat: Zaokraglanie - lamerskie pytanie... (Access)
A juz myslalem ze zaokraglenia mam z glowy...
Moj A'97 liczy tak:
0,005 = 0
1,005 = 1
2,005 = 2
u mnie tak samo, czyli procek mam raczej ok ;-)
A powazniej, przede wszystkim sorry, niepotrzebnie podnioslem alarm.
Okazuje sie, ze wystepuja bledy przy zaokraglaniu (obcinaniu) liczb
zmiennoprzecinkowych. Wystarczy sprobowac np. (chocby w oknie
bezposrednim kodu):
1.005*100+0.5 wynik 101. Zgadza sie? 1.005*100 = 100.5 dodac 0.5 = 101
ale:
Int(1.005*100+0.5) = ... 100 ! Czyli upraszczajac Int(101)=100 :-O
Dzieje sie dlatego, ze w tym przypadku Access wykonuje obliczenia
domyslnie na liczach zmiennoprzecinkowych i byc moze w powyzszym
przypadku wynikiem 1.005*100+0.5 (gdzies w pamieci) jest w
rzeczywistosci 100.999..9999, chociaz wszedzie wyswietlane jest 101. A
potem wykonujac Int (czyli obciecie czesci ulamkowej) na takiej
"niecalkowitej" liczbie wyjdzie... wiadomo co.
Wystarczy sprobowac:
Zreszta operacje zaokraglen, o ktorych tu mowa, M$ zaleca przeprowadzac
tylko na staloprzecinkowym typie Waluta. Sprobowalem to zrobic, w polu
niezwiazanym na formularzu, ale odwolujacym sie bezposrednio do pola
tabeli:
=Int([PoleSzmal]*100+0,5)/100
gdzie [PoleSzmal] jest polem typu Waluta w tabeli - i zaokraglenie juz
jest dla kazdej liczby ok.
W przypadku kodu czy pol niezwiazanych na formularzach/raportach (ale
nie liczacych "bezposrednio" na polach Waluta tabel) wydaje mi sie, ze
wyjsciem jest przeksztalcanie liczb na typ Currency, np.
wynik=Int(CCur(liczba*100+0,5))/100
lub np.
Function Zaokr100 (liczba As Currency)
Zaokr100 = Int(liczba*100+0,5)/100
End Function
Natomiast wydaje mi sie blednym stosowanie CLng.
wg.wzoru: Zaokraglenie = CLng(Liczba * 100) / 100
Z dwoch powodow.
1. Jesli czesc ulamkowa wynosi dokladnie 0,5 CLng zawsze zaogragla ja
do najblizszej *parzystej* liczby calkowitej.
Czyli w odniesieniu do powyzszego wzoru np.
1,035 = 1,04 (najblizsza parzysta do 3 jest 4)
i
1,045 tez = 1,04 (najblizsza parzysta do 4 jest 4... ; powinno byc
chyba 1,05?)
potem
1,055 = 1,06
1,065 = 1,06 itd. itp.
2. Moze mniej istotne - CLng, o czym byla tez tutaj kiedys mowa dziala w
zakresie -2147483648 do 2147483647. Mnozac dla zaokraglen do 2 miejsca
liczbe * 100, otrzymujemy w praktyce zakres do 21474836,47. Przy
operacjach finansowych 21 milionow to calkiem pokazna suma ;-) ale...
Typ Currency oferuje zakres -922337203685477,5808 do
922337203685477,5807 - tyle chyba powinno wystarczyc, nawet po
"zmniejszeniu" o dwie liczby ;-)
Na koniec dla wytrwalych wyciagi z dokumentacji:
Z Knowledge Base M$, nawiasem mowiac w przykladach jest uzywana
wylacznie wyrazenie Int(liczba*100...) a nie CLng
-------
These functions should only be used with Currency data. If used with
Double or Single numbers, yuo may still receive minor rouding errors.
The reason for is that Single and Double numbers are floating point.
They cannot store exact binary representation of decimal fractions.
Therefore there always be some errors. However, Currency values are
scaled integers and can store an exact binary representation of
fractions to 4 decimal places.
----
i jeszcze z helpa o CLng
----------------
<...
Jeśli część ułamkowa wynosi dokładnie 0,5, funkcje CInt i CLng zawsze
zaokrągla część ułamkową do najbliższej parzystej liczby całkowitej. Na
przykład, liczba 0,5 zostanie zaokrąglona do 0, a liczba 1,5 do 2.
-------
Pozdrawiam -
Stanley
Temat: Problem z zaokr±glaniem
Przychodzi -man, i przez 10.65.4.220, pisze w
| Poza tym, ja każdemu i każdej polecam każdy typ rzeczywisty BYLE NIE
| REAL (Tesco i Geant też odpada) - bo jest symulowany (jak w
| komputerach bez FPU), a nie kalkulowany przez koprocesor.
Taaa, pewnie. Takie pytanie, który mamy wiek?
Wybierz poprawną odpowiedź:
a. przedszkolny
b. XX
c. XXI
Jeśli nie wybrałeś c. to nie czytaj dalej, bo i tak nie pomoże.
A jak wybrałem c?
W Delphi 32 bitowym (czyli tak od wersj 2) real jest równoznaczny z
double,
a jak byś bardzo chciał mieć ów symulowany typ to nazywa się real48.
Taaaa? Delphi 3 standard dla kodu
var
a: real;
b: integer;
begin;
a:=0;
for b:=0 to 1000 do
a:=a+1;
showmessage(StrToFloat(a));
end;
generuje kod:
xor eax, eax
mov [ebp-0x06],eax
mov [ebp-0x02],ax
mov ebx, 0x000003e9
lea eax, [ebp-0x06] //
call -0x0005ac2c //
fadd dword ptr [0x0045fcbc] //
lea eax, [ebp-0x06] //
call -0x0005ac0a //
dec ebx
jnz -0x19
Po zamianie Real na Single, linie wyróżnione przez "//" zamieniane są na:
fld dword ptr [ebp-0x04]
fadd dword ptr [0x0045fc2c]
fstp dword ptr [ebp-0x04]
wait
Po zamianie na Double:
fld qword ptr [ebp-0x08]
fadd qword ptr [0x0045fc30]
fstp qword ptr [ebp-0x08]
wait
Po zamianie na Extended:
fld tbyte ptr [ebp-0x0a]
fadd dword ptr [0x0045fc34]
fstp tbyte ptr [ebp-0x0a]
wait
I na Currency:
fild qword ptr [ebp-0x08]
fadd qword ptr [0x0045fc38]
fistp qword ptr [ebp-0x08]
wait
Nie trzeba znać ASMa, by wywnioskować z tego, że Real jest taki, jaki był,
czyli symulowany, nawet w D3. I zgadzam się co do tego, że Real48 jest
i dalej działa (ale powyżej D3), a po jego wprowadzeniu Real jest aliasem
czegoś innego.
Ale po co się bez sensu frustrować? Single, Double, Extended, Currency i
do widzenia...
Pozdrawiam,
Temat: Parę obserwacji nt. dokładności obliczeń
Witam,
Chciałbym się podzielić pewnymi obserwacjami nt. dokładności obliczeń na
liczbach zmiennopozycyjnych i zapytać o radę.
Pewnie temat dla wielu jest znany i oklepany, dla mnie kwestia
stabilności obliczeń była do tej pory znana z teorii.
Tu jest kawałek kodu C++ do testowania:
////////////////////////////////////////////////////////////////////////////
// unstable.cpp
#include <vector
#include <cassert
using namespace std;
vector<doublev;
double tot=0;
void add(double d) {
v.push_back(d);
tot+=d;
}
void check() {
double tot_check=0;
for (size_t i=0; i<v.size(); i++) {
tot_check+=v[i];
}
assert(tot_check==tot);
}
int main()
{
add(3.4200000000000001);
add(1.51000000000000000000000001);
check();
return 0;
}
////////////////////////////////////////////////////////////////////////////
I teraz, zależnie od stopnia optymalizacji, rozwijania funkcji inline
bądź nie, opcji dot. FP, otrzymuje różne wyniki (assert w funkcji check
jest spełniony bądź nie):
1. Kompilacje, które powodują, że assercja nie jest spełniona:
g++ -O3 unstable.cpp
g++ -O2 unstable.cpp
g++ -O1 unstable.cpp
2. Kompilacje, przy których asercja jest spełniona:
g++ -O0 unstable.cpp
g++ -ffloat-store -O1 unstable.cpp
g++ -ffloat-store -O2 unstable.cpp
g++ -ffloat-store -O3 unstable.cpp
g++ -march=pentium4 -mfpmath=sse -msse2 -O1 unstable.cpp
g++ -march=pentium4 -mfpmath=sse -msse2 -O2 unstable.cpp
g++ -march=pentium4 -mfpmath=sse -msse2 -O3 unstable.cpp
W kwestii rozwijania inline, zauważyłem, że rozwijanie lub jego brak
wpływa na wynik zaokrąglania liczb zmiennoprzecinkowych.
Trochę pogrzebałem, i mój stan wiedzy na dzień dzisiejszy, mówi mi, że
ten sam kod maszynowy może dawać różne wyniki w/w obliczeń/zaokrągleń
zależnie od CPU/FPU użytej do wykonania. Ma to miejsce np. w nowych CPU
(=P4), gdzie obecne są m.in. instrukcje typu 'scalar floating point
instructions'.
GCC manual mówi tak (-mfpmath):
sse Use scalar floating point instructions present in the SSE
instruction set. This instruction set is supported by Pentium3 and
newer chips, in the AMD line by Athlon-4, Athlon-xp and Athlon-mp
chips. The earlier version of SSE instruction set supports
only single precision arithmetics, thus the double and extended
precision arithmetics is still done using 387. Later version,
present only in Pentium4 and the future AMD x86-64 chips supports
double precision arithmetics too.
For i387 you need to use -march=cpu-type, -msse or -msse2
switches to enable SSE extensions and make this option effective.
For x86-64 compiler, these extensions are enabled by default.
The resulting code should be considerably faster in the majority of
cases and avoid the numerical instability problems of 387 code, but
may break some existing code that expects temporaries to be 80bit.
This is the default choice for the x86-64 compiler.
Czy to oznacza, że pewność co do przewidywalności obliczeń na liczbach
zmiennoprzecinkowych można mieć jedynie przy uzyciu nowych procesorów z
instrukcjami SSE? Tak to rozumiem, ale czy dobrze?
Inne znane mi rozwiązanie dla zapewnienia stabilności obliczeń na
liczbach float, to rezygnacja/unikanie z rozwijania funkcji inline,
które wykonuja obliczenia/porównania na liczbach float oraz rozbicie
złożonych obliczeń na atomowe operacje z zapamiętaniem wyników
pośrednich w zmiennych.
Wyłączenie optymalizacji również wydaje się rozwiązaywać problem
stabilności obliczeń na float'ach.
A co z wydajnością? Zastosowanie w/w środków na pewno wpłynęłoby na
wydajność negatywnie.
Przyznam bez bicia, nie analizowałem tego jak sobie radzą z w/w
problemami biblioteki do obliczeń o wysokiej precyzji.
W bibliotece nad którą pracuję stosuję tzw. precision model oparty o
siatkę z regulowanym rozstępem linii: 1, 0.1, 0.0.1, itd.
Jeśli ktoś mógłby mi wyjaśnić, lub odesłać do publikacji na temat jak
sobie dobrze poradzić z problemem opisanym wyżej to będę wdzięczny.
Pozdrawiam
Temat: Pytanie o volatile (2)
To wygląda podobnie do teorii względności: z punktu widzenia różnych
procesorów kolejność w czasie tych samych operacji na pamięci może być
różna :-)
Nie tylko kolejność, ale nawet liczba i rozmiary operacji na szynie.
Na przykład na niektórych architekturach dwa zapisy 32-bitowe
do kolejnych komórek mogą zostać przez procesor połączone i
wykonane jako jeden zapis 64-bitowy. Do tego dochodzą rzeczy
takie jak forwarding -- jeśli program najpierw zapisuje jakąś
komórkę pamięci, a chwilę później ją czyta, to procesor może opóźnić
zapis tak, by został wykonany _po_ odczycie i anulować odczyt z pamięci,
a o zwrócenie "nowej" wartości zmiennej dba bufor forwardujący, który
weźmie ją nie z pamięci, tylko z wnętrza procesora, gdzie czeka ona na
zapis.
Z punktu widzenia programu wykonywanego na tym procesorze wszystko
jest OK, ale z punktu widzenia pamięci (nawet nie innych procesorów)
kolejność jest inna.
Na temat modeli spójności pamięci można sobie poczytać tu:
http://portal.acm.org/ft_gateway.cfm?id=160553&type=pdf
O konieczności synchronizowania pamięci musi wiedzieć programista,
który chce uniknąć mutexów tudzież zmiennych condition z powodów
wydajnościowych.
Heh, gdy zachodzi potrzeba wykonania jakiejkolwiek operacji atomowej, to
o wydajności można zapomnieć. Często są to operacje serializowane,
posiadające
dodatkowo semantykę barier. Przed ich wykonaniem procesor czeka na
zakończenie
wykonania wszystkich poprzednich operacji, przez co koszt wykonania takiej
operacji
jest olbrzymi i w przypadku xchg na Pentium 4 wynosi ~92 cykle. Ponieważ
jednostki
wykonawcze są zrównoleglone, oznacza to "stratę" możliwości wykonania ~500
mikroinstrukcji. Jeśli sekcja krytyczna jest bardzo krótka, np. realizuje
wstawienie
elementu do listy dwukierunkowej, to przy koszcie blokowania jest "szumem",
zajmującym
~3--5% czasu blokowanej funkcji. Do tego dochodzą problemy z cache, jeśli
spójność
jest realizowana przez unieważnienia zmodyfikowanych linijek, a nie
śledzenie komunikacji
na szynie i automatyczne uaktualnianie -- linijkę w której jest umieszczona
zmienna dzielona
trzeba wówczas przesłać do drugiego procesora.
Dostępne w zbiorze instrukcji procesora instrukcje barier też są zazwyczaj
zbyt silne, bo
gwarantują wykonanie _wszystkich_ czekających w buforze LSU operacji
zapisu/odczytu,
choć najczęściej interesuje nas tylko spójność kilku wybranych zmiennych
(zwykle tylko
jedna albo dwie).
Na szczęście można sobie z tym radzić za pomocą różnych sztuczek, np. na
większości
architektur forwarding da się "wyłączyć" przez odczyt o większej szerokości
niż
poprzedzający go zapis, np. zapisujemy bajt pod wyrównany adres &x, a
następnie
odczytujemy 32 bity spod &x. W takiej sytuacji m.in. IA-32 wymusi
synchronizację
komórki wskazanej przez x i przechowywanej w forwarding bufferze z pamięcią
podręczną.
W często spotykanych modelach single reader-single writer też często można
obyć
się bez operacji atomowych korzystając z tego, że modele pamięci
implementowane
przez procesor nie zmieniają kolejności zapisów. Wówczas wystraczy mieć dwa
liczniki,
a pisarz modyfikuje jeden przed zapisem, a drugi po zapisie danych
dzielonych.
Jeśli są one równe, to czytelnik uznaje odczytane dane dzielone za poprawne,
w
przeciwnym razie ponownie próbuje szczęścia. Są jeszcze rozwiązania oparte
na
licznikach pracujących w kodzie Graya dla liczników szerszych niż słowo albo
jeśli
maszyna nie zapewnia atomowych zapisów/odczytów-- ponieważ tylko jedna cyfra
może się zmienić pomiędzy dwoma słowami kodowymi, to czytelnik nigdy nie
odczyta
z licznika wartości "pośredniej", a tylko albo wartość starą, albo nową.
Sztuczek jest wiele i są warte świeczki, bo krótkie sekcje krytyczne mogą
przyspieszyć
nawet o rząd wielkości w porównaniu do spinlocka i co najmniej tyle samo w
porównaniu
do muteksa (muteks to zwykle spinlock + kolejkowanie w przypadku kolizji).
:-)
Pozdrawiam
Piotr Wyderski
Temat: Photoshop nie widzi ponad 2 GB RAM?!
W wielu aplikacjach serwerowych "program" (powiedzmy SQL Server)
składa się z wielu równoległych procesów i wtedy możliwe jest
efektywne wykorzystanie znacznie większej pamięci.
Tak właśnie jest.
Inna rzecz, że
programy "single user" - takie jak Photoshop - raczej nie wykorzystują
tego mechanizmu i nawet jeśli używają procesów pobocznych, to
okazjonalnie (np. podczas drukowania).
Tak właśnie jest. Pytającemu raczej zależało na zwiększeniu możliwości
obróbki dużych bitmap, a to by oznaczało, że PhotoShop musiałby dzielić
bitmapę na kawałki i obrabiać ją w różnych procesach. To byłoby chyba trudne
do zrealizowania (ale - nie niemożliwe).
W praktyce oznacza to, że zainstalowanie więcej niż 2 GB RAM zapewni
programowi właśnie pełne 2 GB, którymi nie będzie się musiał dzielić
z kernelem. Tyle, że kernel nijak nie wykorzysta pozostałych 2 GB
(w każdym razie nie na workstacji, co innego, gdyby to był serwer) -
czyli 4 GB to tak o 1.5 GB za dużo...
Ja to rozumiem inaczej, a mianowicie "każdy proces" dzieli 4GB po połowie
między kernel, a aplikację, czyli jeśli uruchamiam PhotoShopa, to on ma 2GB
do obsługi danych użytkownika i 2GB dla obsługi systemu, ale - w ramach
obsługi tej aplikacji. Czyli system ma 2GB po to, żeby obsługiwać tylko ten
proces (tak mi się wydaje). Czyli - czy to jest serwer, czy nie - to moim
zdaniem - nie ma znaczenia. Po prostu - jak zostanie uruchomiona usługa
"serwera", to znów zostanie stworzony proces, w którym 2GB będzie miał
system i 2GB - aplikacja. Wszelkie ruchy na serwerze będą odbywały się
właśnie w tych 2GB aplikacji, poza kodem wykonywanym przez system. Czyli -
jeśli programista w kodzie tego serwera zarezerwuje pamięć na ściągany plik,
to on zostanie zarezerwowany z pamięci aplikacji, ale - jeśli wywołam
procedurę systemową, która ten plik ma zapisać na dysku, to w tym celu
potrzebne są jakieś bufory do przesłania danych, których ja nie tworzę. One
zostaną utworzone automatycznie w momencie wykonywania funkcji i będą
przydzielone z tej drugiej połówki. Zaznaczam, że to są tylko moje
przemyślenia, bo jak jest naprawdę, to trudno dociec.
Można dyskutować, czy takie rozwiązanie jest optymalne, ale - nie jest ono
chyba całkiem bez sensu. Powiedzmy, że użytkownik stworzył dużą bitmapę
(1GB) i teraz chce ją wyswietlić w pomniejszeniu na ekranie. Zleca systemowi
operację "rzutowania" tej bitmapy na ekran. Od tego momentu użytkownik
(programista) nie przejmuje się dalszą akcją, a przecież trzeba tę bitmapę
"wciągnąć" do pamięci i pomniejszyć. To zrobi system w swojej połówce
pamięci. Tak więc podział po równo jest chyba optymalny.
Zaznaczam, że dyskutujemy w tej chwili o możliwości adresowania, a nie
wydajności. Rzecz jasna, że uruchamianie kolejnych programów (procesów) (np.
procesu serwera) zmniejszy wydajność maszyny, bo po pierwsze liczba
procesorów jest stała i po drugie 4GB dla każdego procesu musi "pomieścić"
się w fizycznie dostępnej pamięci i na dysku. Tak więc - moim zdaniem -
pamięci nigdy za dużo. Nawet jeśli PhotoShop nie widzi więcej niż 2GB, to
operacje systemowe na danych w moim programie powinny być wykonywane
sprawniej (mniej odwołań do dysku). Tak mi sie wydaje, ale - kto to wie?
Pozdrawiam
Stefan Nawrocki
Temat: dlaczego 12,3 to 12,3000001907349
Nie, bowiem niczego nie dowodzi. A właściwie pokazuje, że fizycy i Ty
zbytnio wierzcie w to co wypluwa stdio. Dla liczb typu float
Przekonajmy sie zatem...
Można przypuszczać, że bibllioteka stdio jest tak zoptymalizowana, że
w przypadku liczb single przyjmuje, że cyfry powyżej 7 lub 8 są zerem,
dla double analogicznie.
Na jakiej podstawie? Mam przed oczami kod printfa i nie widac
w nim niczego takiego, co sugerujesz. A wczesniej proponuje sie
przyjzec chocby specyfikacji kwalifikatora "%f". Nie w printfie
jest jednak problem, pokaze Ci, ze i bez niego widac smieci.
Zatem jeśli dokładność będzie sztucznie zwiększana poprzez zrzutowanie
float-double, to wyświetlający (inteligentnie) stdio będzie produkował
pozornie błędne wyniki, tak jak w pokazanym przez Ciebie programie.
A to jest juz wniosek wynikajacy z blednego zalozenia, wiec choc
prawdziwy -- nie wnosi nic do sprawy. Zalozyles sobie cos, co nie
jest prawda i uzywasz tego do udowodnienia swojego rozumowania.
I powodem tego nie jest strata dokładności (co jest brednią do kwadratu),
ale domniemanie przez procedury wyświetlające wyższej dokładności liczby.
Zatem uprzejmie prosze o wytlumaczenie ponizszego (istotna dla naszej
dyskusji czesc zdisasemblowanego programiku z poprzedniego postu):
7:
8: float f = 1.3f;
0040EA38 mov dword ptr [ebp-4],3FA66666h
9: double d = f;
0040EA3F fld dword ptr [ebp-4]
0040EA42 fstp qword ptr [ebp-0Ch]
10:
11: f = (float)(f * 1000.0);
0040EA45 fld dword ptr [ebp-4]
0040EA4E fstp dword ptr [ebp-4]
12: d = d * 1000.0;
0040EA51 fld qword ptr [ebp-0Ch]
0040EA5A fstp qword ptr [ebp-0Ch]
13: tu sie zaczyna printf
A oto przebieg programu:
9: f = 1.30000; d = -9.2559631349318e+061, czyli smiec ze stosu
10: f = j.w.; d = 1.2999999523163 !!!
12: f = 1300.00; d = j.w.
13: f = j.w.; d = 1299.9999523163
single : Valid ST(0) 1.29999995 23162842 | 3FFF A666 6600 0000 0000
Sam wlasnie pokazales wlasna wiare w bzdury -- popatrz sam, co
wygenerowal TD. Mantysa single ma 23 bity, skad wiec ten
dodatkowy smiec 5231...? Oto wartosc tej liczby (0x3FA66666)
policzona _recznie_, bez wykorzystania jakiegokolwiek drukownia
maszynowego:
liczba = 0011.1111.1010.0110.0110.0110.0110.0110
znak (0) = "+"
mantysa znormalizowana = 0111.1111 = 0x7f
cecha = 1010.0110.0110.0110.0110.0110 = 1.3
Test w Octave:
v = [1,0,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0];
t=0; for i=1:24, t = t+v(i)*2^(-i); end; t
t = 0.650, czyli 1.3 (0.65*2) w znormalizowanym zapisie zmiennoprzecinkowym.
QED. Mozna prosic o komentarz?
Pozdrawiam
Piotr Wyderski
PS. Wnioskiem pobocznym jest to, ze debugger VC dokonuje
poprawnego wyswietlania liczby, uwzgledniajac jej rozmiar, nie
wykonujac po drodze bzdurnych konwersji do wiekszej precyzji.
Temat: dobre praktyki pisania aplikacji internetowych (PHP)
1. W serwisie jest czesc publiczna i prywatna (logowanie - formularzy).
Czy
po uwierzytelnieniu wystarczy ustawic $_SESSION['identyfikator'] = 44; ?
Czy
to wystarczy, zeby uznac, ze uzytkownik zostal pozytywnie zweryfikowany i
dawac mu dostep do kolejnych stron prywatnych?
Tak. A generalnie nalezy maksymalnie oddzielić proces autentykacji
(okreslania nazwy użytkownika) od procesu sprawdzania uprawnień do zasobów.
Jeśli używasz Apache pomyśl o wykorzystaniu jednego z setek dostępnych
modułów autentykacji (od http auth poprzez formatki na CAS-ach i LDAPAch
skończywszy). W aplikacji masz zawsze "jednolity" interfejs z nazwą
użytkownika - zmienna REMOTE_USER. Resztę robi oddzielny kod serwera.
2. Jak bede mial kikaset, kilka tysiecy uzytkownikow, to do wysylania np.
newslettera chyba funkcja PHP mail() nie bedzie wystarczajaca. Znalazlem
na
stronie ZEND http://www.zend.com/codex.php?id=1136&single=1 takie
rozwiazanie uruchamiajace polecenia powloki (eliminuje jak rozmiem
ograniczenie wykonania skryptu). Znacie jakies inne rozwiazania w tym
zakresie (nie wymagajace uruchamiania polecen zewnetrznych)?
Jeśli akcję tę uruchamia człowiek (główny redaktor) można ją podzilić na
porcje po kilkadziesiat maili i autmoatycznie submitować kolejną porcję.
Operator czeka wówczas i widzi jak mu się odświeża przeglądarka z
"licznikiem" maili.
a) Czy wyswietlanie powinno byc zaimplementowane w ramach klasy, czy na
zewnatrz, tzn. bylby sobie template, ktory by korzystal z wlasciwosci
obietu
<h1<?= $artykulik-_getTitle; ?</h1. To drugie rozwiazanie wydaje mi
sie
lepsze, bo oddzielam operacje na danych od ich prezentacji, tak jak xml i
css :)))
Tak, widok powinien być wyraźnie wydzielony. Myśl kategoriami "Obiekt klasy
artykuł" i "Obiekt klasy widok artykułu w formie pełniej", "Obiekt widoku
tego samego artykułu jako newsa" itd.
b) Gdzie powinna byc prowadzona weryfikacja danych w obiekcie czy zanim
dane
do niego trafia? Kupilem ksiazke Bezpiecznie programowanie w PHP i jest
tam
sporo fajnych pomyslow, tylko gdzie je umiescic. Tu z kolei sklanialby sie
do wrzucenia tego w klase, bo mozna wykorzystywac wiele razy ten sam kod i
wiadomo co i w jaki sposob sprawdzac.
Jak to gdzie :). W obiektach AKCJI. Klasa "Edycja treści artykułu"
dziedzicząca po "Ogólny obiekt akcji z bezpiecznym przetworzeniem danych
POST/GET"
c) Czy programowanie obiektowe jest dobre na wszystko? Mam strone z lista
Na wszystko
artykulow, czy do ich wyswietlenia wogole uzywac obiektow? Wydaje mi sie
to
bez sensu, bo najpiew bym musial wykonac zapytanie do bazy danych o
identyfikatory artykulow (wszystkich lub spelniajacych kryteria
wyszukiwania) a nastepnie w pentli budowac obiekt, wyswietlac jego
wlasciwosci, niszczyc obiekt i tak w kolko. Moze od razu lepiej zrobic to
bez obiektow?
Najważniejszym obiektem jest tu nie artykuł tylko lista !. To na niej
operujesz - sortowanie, porcjowanie itd. Jeśli nie przewidujesz
skomplikowanych akcji na wyświetlanych rekordach - wystarczy je przetwarzać
jako napisy. Oczywiście dziedziczy z "Uniwersalnej listy zasilanej z SQL"
itd.
4. Jeszcze o obiektach :) Tym razem klasa Uzytkownik, a w niej wlasciwosci
takie jak nazwa, email, haslo, rozne ustawienia. W punkcie pierszym
- czy na kazdej stronie mam budowac obiekt od nowa i korzystac z jego
wlasciwosci,
Tak czynisz np. z obiektem widoku ("Obiekt klasy widok artykułu w formie
pełniej") nie ma potrzeby by żył dłuzej niż 1 request.
- czy moze do sesji zapisac caly obiekt?
Tak z robisz w przypadku obiektu "Artykuł" czy "Lista artykułów"
5. I na koniec pytanie zwiazane z MySQL. We wspomnianej ksiazce autor
rekomenduje wykorzystywanie funkcji htmlentities() do prezentacji wynikow
na
stronie i mysql_real_escape_string() do zapisywania danych z bazie. Czy
dobrze rozumiem, ze przed wyslaniem danych do bazy nie trzeba, na
dodatkowy
wszelki wypadek, traktowac ich funkcja htmlentities()? Wtedy w bazie
zapisane beda &...; i przy wyszukiwaniu tez trzeba bedzie szukany ciag
traktowac ta sama funkcja. Zgadza sie?
Nie trzeba.
A na koniec pytanie najważniejsze - czemu chcesz się katować na siłę PHP ?
Istnieje tyle lepszych języków programowania :)
Temat: Mplayer i AtiRageProTurbo
has been fingerprinted by Szymon Wróblewski:
No tak faktycznie jest to wazne, ale patrz tytul posta :))
A, prawda. Tak, ja chyba faktycznie nie czytam tematów.
jedynie dzwiek jest troche przesuniety.
We wszystkich filmach? Jeśli się rozchodzi o stały okres czasu, to można
to jakąś opcją mplayera skorygować (jest w manualu). Jeśli się jednak
"progresywnie rozchodzi", coraz bardziej i bardziej, to możesz spróbować
'-framedrop' - może chodzi tylko o drobną korektę która zbytnio nie
zaważy na jakości.
Inna ciekawostka QuickViewPro, taki dosowy player, radzi sobie doskonale
na moim sprzecie, wyswietlanie filmow idealne, wiec czego nie rozumiem :))
Jestem ogolnie pelen podziwu dla Linuxa, ale zeby w takim momecie
taki prymityw jak dos go "nokautowal" :))
Dos jest single-tasking. Dowolny program może mieć nielimitowany dostęp
do sprzętu. Linux sobie na to nie może pozwolić, musi dojść co najmniej
jeszcze jedna warstwa pośrednicząca - a to kosztuje. Coś za coś. To tak,
jak z przepisaniem pierwszych systemów operacyjnych z asemblera
w C - prędkość spadła o 20%, o tyle samo wzrosło zużycie ramu - ale
zarządzanie kodem, konserwacja itp. stały się łatwiejsze i możliwy był
postęp. Przypuszczalnie ten dosowy program miał prawo do grzebania
bezpośrednio w karcie graficznej, być może był nawet optymalizowany
specjalnie pod tę kartę (i inne) - ale mplayer musi używać tutaj fb,
który nawet zbyt dobry sam w sobie nie jest...
| Jeśli masz kartę graficzną, która zajmie się (w pełni sprzętowo)
| konwersją kolorów i skalowaniem obrazu.
Ktore to moga byc karty? Wlasnie ponoc wiekszosc kart Ati ma
taka akceleracje, chyba ze ta moja nie :))
Większość kart _w ogóle_ ma takie możliwości. Problem jest ze
sterownikami - jeśli system nie wie, jak włączyć odpowiednie funkcje
karty to ich po prostu nie włączy. Pod Windows masz łatwo - sterowniki
dostajesz od producenta. Pod Linuksem albo producent musi łaskawie
pomóc, dając dostęp do choćby części specyfikacji, albo koderzy
w męczarniach, metodą prób i błędów rozpracowują karty "na macanta"
- ale to nie daje tak dobrych rezultatów i długo trwa. Tak że oprócz
samej karty ważne jest jeszcze, jakie ma wsparcie.
W źródłach mplayera (katalog drivers/radeon) znajduje się
eksperymentalny moduł "dopalający" dla kart Rage128 - ale Rage Pro to
pewnie coś innego...
| już bym nie schodził). Ja mam najtańszego Matroksa jakiego udało mi
| się wypatrzeć (G200) i na procesorze 333MHz pełnoekranowe oglądanie
| divx-ów obciąża procesor zwykle w ~30%. Czasem więcej, czasem mniej.
Hmm imponujace!!!
Raczej zasmucające, bo taki "performance" powinna (technicznie patrząc)
dawać znakomita większość kart. Powiedzmy, że to są "normalne" osiągi
wielu kart - gdyby producenci nie kryli się tak ze swoimi "tajemnicami",
to tak by mogła mieć znakomita większość linuksiarzy. Przecież moja G200
ma już swoje latka.
Ma to jedną dobrą stronę - można upolować na Allegro takie właśnie karty
za nieduże pieniądze - bo ludzie z Windows się ich pozbywają by zrobić
miejsce dla nowego GeForce4 czy innych.
Zainstaluje X'y ale czy nie mam za malo ramu? Tylko 64MB.
Spokojnie, jak długo nie planujesz używania całego Gnome czy KDE to
wystarczy. Ja długi czas używałem na 48MB. A X-owe rozszerzenie
XVideo może da większe przyspieszenie twojej karcie. Możesz też
spróbować z tym modułem dla Rage128 z mplayera, ale on pewnie nie
zadziała.
Strona 2 z 3 • Znaleziono 119 rezultatów • 1, 2, 3